Java tutorial
package org.commonfarm.security.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Cookie; /** * Seraph utility class for dealing with cookies * * Includes code from Jive 1.2.4 (released under the Apache license) */ public class CookieUtils { private static final Log log = LogFactory.getLog(CookieUtils.class); // the key which represents the list of cookies to add for this request (in case of redirect) public static final String COOKIES_TO_SEND = "atlassian.core.web.cookies.unsent"; // Character used to separate username and password in persistent cookies. // 0x13 == "Device Control 3" non-printing ASCII char. Unlikely to appear in a username private static final char DELIMITER = 0x13; //"Tweakable" parameters for the cookie encoding. NOTE: changing these //and recompiling this class will essentially invalidate old cookies. private final static int ENCODE_XORMASK = 0x5A; private final static char ENCODE_CHAR_OFFSET1 = 'C'; private final static char ENCODE_CHAR_OFFSET2 = 'i'; /** * Invalidate the specified cookie and delete it from the response object. * * @param response The HttpServletResponse object, known as "response" in a JSP page. * @param cookieName The name of the cookie you want to delete. * @param path of the path the cookie you want to delete. */ public static void invalidateCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String path) { log.debug("CookieUtils.invalidateCookie " + cookieName + " for path " + path); setCookie(request, response, cookieName, null, 0, path); } /** * Invalidate the specified cookie and delete it from the response object. Deletes only cookies mapped * against the root "/" path. Otherwise use * {@link #invalidateCookie(HttpServletRequest, HttpServletResponse, String, String)} * * @param response The HttpServletResponse object, known as "response" in a JSP page. * @param cookieName The name of the cookie you want to delete. * @see #invalidateCookie(HttpServletRequest, HttpServletResponse, String, String) */ public static void invalidateCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) { invalidateCookie(request, response, cookieName, "/"); } /** * Returns the specified Cookie object, or null if the cookie does not exist. * * @param request The HttpServletRequest object, known as "request" in a * JSP page. * @param name the name of the cookie. * @return the Cookie object if it exists, otherwise null. */ public static Cookie getCookie(HttpServletRequest request, String name) { Cookie cookies[] = request.getCookies(); if (cookies == null || name == null || name.length() == 0) { return null; } //Otherwise, we have to do a linear scan for the cookie. for (int i = 0; i < cookies.length; i++) { if (cookies[i].getName().equals(name)) { return cookies[i]; } } return null; } /** * Sets a cookie * * This will also put the cookie in a list of cookies to send with this request's response * (so that in case of a redirect occurring down the chain, the first filter * will always try to set this cookie again) */ public static Cookie setCookie(HttpServletRequest request, HttpServletResponse response, String name, String value, int maxAge, String path) { log.debug("CookieUtils.setCookie " + name + ":" + value); Cookie cookie = new Cookie(name, value); cookie.setMaxAge(maxAge); cookie.setPath(path); response.addCookie(cookie); return cookie; } /** * Returns the value of the specified cookie as a String. If the cookie * does not exist, the method returns null. * * @param request the HttpServletRequest object, known as "request" in a * JSP page. * @param name the name of the cookie * @return the value of the cookie, or null if the cookie does not exist. */ public static String getCookieValue(HttpServletRequest request, String name) { Cookie cookie = getCookie(request, name); if (cookie != null) { return cookie.getValue(); } return null; } /** * Builds a cookie string containing a username and password.<p> * * Note: with open source this is not really secure, but it prevents users * from snooping the cookie file of others and by changing the XOR mask and * character offsets, you can easily tweak results. * * @param username The username. * @param password The password. * @return String encoding the input parameters, an empty string if one of * the arguments equals <code>null</code>. */ public static String encodePasswordCookie(String username, String password) { return encodePasswordCookie(username, password, new String(new char[] { DELIMITER, ENCODE_CHAR_OFFSET1, ENCODE_CHAR_OFFSET2 })); } /** * Builds a cookie string containing a username and password, using offsets to customise the encoding.<p> * * Note: with open source this is not really secure, but it prevents users * from snooping the cookie file of others and by changing the XOR mask and * character offsets, you can easily tweak results. * * @param username The username. * @param password The password. * @param encoding A String used to customise cookie encoding (only the first 3 characters are used) * @return String encoding the input parameters, an empty string if one of * the arguments equals <code>null</code>. */ public static String encodePasswordCookie(String username, String password, String encoding) { StringBuffer buf = new StringBuffer(); if (username != null && password != null) { char offset1 = (encoding != null && encoding.length() > 1) ? encoding.charAt(1) : ENCODE_CHAR_OFFSET1; char offset2 = (encoding != null && encoding.length() > 2) ? encoding.charAt(2) : ENCODE_CHAR_OFFSET2; byte[] bytes = (username + DELIMITER + password).getBytes(); int b; for (int n = 0; n < bytes.length; n++) { b = bytes[n] ^ (ENCODE_XORMASK + n); buf.append((char) (offset1 + (b & 0x0F))); buf.append((char) (offset2 + ((b >> 4) & 0x0F))); } } return buf.toString(); } /** * Decodes a cookie string containing a username and password. * @param cookieVal The cookie value. * @return String[] containing the username at index 0 and the password at * index 1, or <code>{ null, null }</code> if cookieVal equals * <code>null</code> or the empty string. */ public static String[] decodePasswordCookie(String cookieVal) { return decodePasswordCookie(cookieVal, new String(new char[] { DELIMITER, ENCODE_CHAR_OFFSET1, ENCODE_CHAR_OFFSET2 })); } /** * Decodes a cookie string containing a username and password. * @param cookieVal The cookie value. * @param encoding A String used to customise cookie encoding (only the first 3 characters are used) - should be the same string you used to encode the cookie! * @return String[] containing the username at index 0 and the password at * index 1, or <code>{ null, null }</code> if cookieVal equals * <code>null</code> or the empty string. */ public static String[] decodePasswordCookie(String cookieVal, String encoding) { // check that the cookie value isn't null or zero-length if (cookieVal == null || cookieVal.length() <= 0) { return null; } char offset1 = (encoding != null && encoding.length() > 1) ? encoding.charAt(1) : ENCODE_CHAR_OFFSET1; char offset2 = (encoding != null && encoding.length() > 2) ? encoding.charAt(2) : ENCODE_CHAR_OFFSET2; // decode the cookie value char[] chars = cookieVal.toCharArray(); byte[] bytes = new byte[chars.length / 2]; int b; for (int n = 0, m = 0; n < bytes.length; n++) { b = chars[m++] - offset1; b |= (chars[m++] - offset2) << 4; bytes[n] = (byte) (b ^ (ENCODE_XORMASK + n)); } cookieVal = new String(bytes); int pos = cookieVal.indexOf(DELIMITER); String username = (pos < 0) ? "" : cookieVal.substring(0, pos); String password = (pos < 0) ? "" : cookieVal.substring(pos + 1); return new String[] { username, password }; } }