| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.jsecurity.web.attr; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import static org.jsecurity.web.WebUtils.toHttp; |
| |
| import javax.servlet.ServletRequest; |
| import javax.servlet.ServletResponse; |
| import javax.servlet.http.Cookie; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import java.beans.PropertyEditor; |
| |
| /** |
| * A <tt>CookieAttribute</tt> stores an object as a {@link Cookie} for access on later requests. |
| * |
| * @author Les Hazlewood |
| * @author Peter Ledbrook |
| * @since 0.2 |
| */ |
| public class CookieAttribute<T> extends AbstractWebAttribute<T> { |
| |
| private static final Log log = LogFactory.getLog(CookieAttribute.class); |
| |
| /** |
| * The number of seconds in one year (= 60 * 60 * 24 * 365). |
| */ |
| public static final int ONE_YEAR = 60 * 60 * 24 * 365; |
| /** |
| * This is the same value as Integer.MAX_VALUE, and while Tomcat does fine with cookie max age with this value, |
| * Jetty apparently has problems with it. If you're using Jetty, you might want to use the |
| * {@link #ONE_YEAR ONE_YEAR} constant or another value. |
| */ |
| public static final int INDEFINITE = Integer.MAX_VALUE; |
| |
| /** |
| * <code>null</code>, indicating the cookie should be set on the request context root. |
| */ |
| public static final String DEFAULT_PATH = null; |
| /** |
| * <code>-1</code>, indicating the cookie should expire when the browser closes. |
| */ |
| public static final int DEFAULT_MAX_AGE = -1; |
| /** |
| * Default value is <code>false</code>. |
| */ |
| public static final boolean DEFAULT_SECURE = false; |
| |
| private String path = DEFAULT_PATH; |
| private int maxAge = DEFAULT_MAX_AGE; |
| private boolean secure = DEFAULT_SECURE; |
| |
| public CookieAttribute() { |
| } |
| |
| /** |
| * Constructs a <tt>CookieAttribute</tt> using a {@link Cookie Cookie} with the specified {@link Cookie#getName() name} |
| * using the request context's path and with a {@link Cookie#setMaxAge(int) maxAge} of <tt>-1</tt>, indicating the |
| * Cookie will persist until browser shutdown. |
| * |
| * @param name the Cookie {@link Cookie#getName() name} |
| */ |
| public CookieAttribute(String name) { |
| super(name); |
| } |
| |
| /** |
| * Constructs a <tt>CookieAttribute</tt> using a {@link Cookie Cookie} with the specified |
| * {@link Cookie#getName() name} and {@link Cookie#getPath() path}. |
| * |
| * <p>A <tt>null</tt> <tt>path</tt> value means the request context's path will be used by default. |
| * |
| * <p>The Cookie's {@link Cookie#getMaxAge() maxAge} will be <tt>-1</tt>, indicating the Cookie will persist until |
| * browser shutdown. |
| * |
| * @param name the Cookie {@link Cookie#getName() name} |
| * @param path the Cookie {@link Cookie#setPath(String) path}. |
| */ |
| public CookieAttribute(String name, String path) { |
| super(name); |
| setPath(path); |
| } |
| |
| /** |
| * Constructs a <tt>CookieAttribute</tt> using a {@link Cookie Cookie} with the specified |
| * {@link Cookie#getName() name} and {@link Cookie#getMaxAge() maxAge}. |
| * |
| * <p>The Cookie's {@link javax.servlet.http.Cookie#getPath() path} will be the <tt>Request</tt>'s |
| * {@link javax.servlet.http.HttpServletRequest#getContextPath() context path}. |
| * |
| * @param name the Cookie {@link javax.servlet.http.Cookie#getName() name}; |
| * @param maxAge the Cookie {@link Cookie#getMaxAge() maxAge} |
| */ |
| public CookieAttribute(String name, int maxAge) { |
| super(name); |
| setMaxAge(maxAge); |
| } |
| |
| /** |
| * Constructs a <tt>CookieAttribute</tt> using a {@link Cookie Cookie} with the specified |
| * {@link Cookie#getName() name}, {@link javax.servlet.http.Cookie#getPath() path}, and |
| * {@link Cookie#getMaxAge() maxAge}. |
| * |
| * @param name the Cookie {@link Cookie#getName() name} |
| * @param path the Cookie {@link Cookie#setPath(String) path}. |
| * @param maxAge the Cookie {@link Cookie#getMaxAge() maxAge} |
| */ |
| public CookieAttribute(String name, String path, int maxAge) { |
| this(name, path); |
| setMaxAge(maxAge); |
| } |
| |
| /** |
| * Constructs a <tt>CookieAttribute</tt> using a {@link Cookie Cookie} with the specified |
| * {@link Cookie#getName() name}, {@link javax.servlet.http.Cookie#getPath() path}, and |
| * {@link Cookie#getMaxAge() maxAge}, utilizing the specified <tt>PropertyEditor</tt> to perform value/string |
| * conversion on the object stored as a cookie. |
| * |
| * @param name the Cookie {@link Cookie#getName() name} |
| * @param path the Cookie {@link Cookie#setPath(String) path}. |
| * @param maxAge the Cookie {@link Cookie#getMaxAge() maxAge} |
| * @param editorClass the <tt>PropertyEditor</tt> to perform value/string conversion on the object stored as a |
| * Cookie. |
| */ |
| public CookieAttribute(String name, String path, int maxAge, Class<? extends PropertyEditor> editorClass) { |
| super(name, editorClass); |
| setPath(path); |
| setMaxAge(maxAge); |
| } |
| |
| /** |
| * Returns the Cookie's {@link Cookie#getPath() path} setting. If <tt>null</tt>, the <tt>request</tt>'s |
| * {@link javax.servlet.http.HttpServletRequest#getContextPath() context path} will be used. |
| * |
| * <p>The default is <code>null</code>.</p> |
| * |
| * @return the Cookie's path, or <tt>null</tt> if the request's context path should be used as the path when the |
| * cookie is created. |
| */ |
| public String getPath() { |
| return path; |
| } |
| |
| /** |
| * Sets the Cookie's {@link Cookie#getPath() path} setting. If the argument is <tt>null</tt>, the <tt>request</tt>'s |
| * {@link javax.servlet.http.HttpServletRequest#getContextPath() context path} will be used. |
| * |
| * <p>The default is <code>null</code>.</p> |
| * |
| * @param path the Cookie's path, or <tt>null</tt> if the request's context path should be used as the path when the |
| * cookie is created. |
| */ |
| public void setPath(String path) { |
| this.path = path; |
| } |
| |
| /** |
| * Returns the Cookie's {@link Cookie#setMaxAge(int) maxAge} setting. Please see that JavaDoc for the semantics on |
| * the repercussions of negative, zero, and positive values for the maxAge. |
| * |
| * <p>The default value is <code>-1</code>, meaning the cookie will expire when the browser is closed.</p> |
| * |
| * @return the Cookie's {@link Cookie#setMaxAge(int) maxAge} |
| */ |
| public int getMaxAge() { |
| return maxAge; |
| } |
| |
| /** |
| * Sets the Cookie's {@link Cookie#setMaxAge(int) maxAge} setting. Please see that JavaDoc for the semantics on |
| * the repercussions of negative, zero, and positive values for the maxAge. |
| * |
| * <p>The default value is <code>-1</code>, meaning the cookie will expire when the browser is closed.</p> |
| * |
| * @param maxAge the Cookie's {@link Cookie#setMaxAge(int) maxAge} |
| */ |
| public void setMaxAge(int maxAge) { |
| this.maxAge = maxAge; |
| } |
| |
| public boolean isSecure() { |
| return secure; |
| } |
| |
| public void setSecure(boolean secure) { |
| this.secure = secure; |
| } |
| |
| /** |
| * Returns the cookie with the given name from the request or <tt>null</tt> if no cookie |
| * with that name could be found. |
| * |
| * @param request the current executing http request. |
| * @param cookieName the name of the cookie to find and return. |
| * @return the cookie with the given name from the request or <tt>null</tt> if no cookie |
| * with that name could be found. |
| */ |
| private static Cookie getCookie(HttpServletRequest request, String cookieName) { |
| Cookie cookies[] = request.getCookies(); |
| if (cookies != null) { |
| for (Cookie cookie : cookies) { |
| if (cookie.getName().equals(cookieName)) { |
| return cookie; |
| } |
| } |
| } |
| return null; |
| } |
| |
| public T onRetrieveValue(ServletRequest request, ServletResponse response) { |
| T value = null; |
| |
| String stringValue; |
| Cookie cookie = getCookie(toHttp(request), getName()); |
| if (cookie != null) { |
| stringValue = cookie.getValue(); |
| if (log.isInfoEnabled()) { |
| log.info("Found string value [" + stringValue + "] from HttpServletRequest Cookie [" + getName() + "]"); |
| } |
| value = fromStringValue(stringValue); |
| } else { |
| if (log.isDebugEnabled()) { |
| log.debug("No value found in request Cookies under cookie name [" + getName() + "]"); |
| } |
| } |
| |
| return value; |
| } |
| |
| public void onStoreValue(T value, ServletRequest servletRequest, ServletResponse servletResponse) { |
| |
| HttpServletRequest request = toHttp(servletRequest); |
| HttpServletResponse response = toHttp(servletResponse); |
| |
| String name = getName(); |
| int maxAge = getMaxAge(); |
| String path = getPath() != null ? getPath() : request.getContextPath(); |
| |
| String stringValue = toStringValue(value); |
| Cookie cookie = new Cookie(name, stringValue); |
| cookie.setMaxAge(maxAge); |
| cookie.setPath(path); |
| if (isSecure()) { |
| cookie.setSecure(true); |
| } |
| |
| response.addCookie(cookie); |
| if (log.isTraceEnabled()) { |
| log.trace("Added Cookie [" + name + "] to path [" + path + "] with value [" + |
| stringValue + "] to the HttpServletResponse."); |
| } |
| } |
| |
| public void removeValue(ServletRequest servletRequest, ServletResponse response) { |
| HttpServletRequest request = toHttp(servletRequest); |
| Cookie cookie = getCookie(request, getName()); |
| if (cookie != null) { |
| cookie.setMaxAge(0); |
| //JSEC-94: Must set the path on the outgoing cookie (some browsers don't retain it from the |
| //retrieved cookie?) |
| cookie.setPath(getPath() == null ? request.getContextPath() : getPath()); |
| cookie.setSecure(isSecure()); |
| toHttp(response).addCookie(cookie); |
| } |
| } |
| } |