1
0
mirror of synced 2026-08-05 17:57:15 +00:00

SEC-1734: AbstractRememberMeServices will now default to using a secure cookie if the connection is secure. The behaviour can be overridden by setting the useSecureCookie property in which case the cookie will either always be secure (true) or never (false).

This commit is contained in:
Luke Taylor
2011-05-09 13:36:23 +01:00
parent 396eced291
commit 6e91786f92
5 changed files with 43 additions and 18 deletions
@@ -56,7 +56,7 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
private boolean alwaysRemember;
private String key;
private int tokenValiditySeconds = TWO_WEEKS_S;
private boolean useSecureCookie = false;
private Boolean useSecureCookie = null;
private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
public void afterPropertiesSet() throws Exception {
@@ -296,9 +296,6 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
/**
* Sets a "cancel cookie" (with maxAge = 0) on the response to disable persistent logins.
*
* @param request
* @param response
*/
protected void cancelCookie(HttpServletRequest request, HttpServletResponse response) {
logger.debug("Cancelling cookie");
@@ -310,7 +307,11 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
}
/**
* Sets the cookie on the response
* Sets the cookie on the response.
*
* By default a secure cookie will be used if the connection is secure. You can set the {@code useSecureCookie}
* property to {@code false} to override this. If you set it to {@code true}, the cookie will always be flagged
* as secure.
*
* @param tokens the tokens which will be encoded to make the cookie value.
* @param maxAge the value passed to {@link Cookie#setMaxAge(int)}
@@ -322,7 +323,13 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
Cookie cookie = new Cookie(cookieName, cookieValue);
cookie.setMaxAge(maxAge);
cookie.setPath(getCookiePath(request));
cookie.setSecure(useSecureCookie);
if (useSecureCookie == null) {
cookie.setSecure(request.isSecure());
} else {
cookie.setSecure(useSecureCookie);
}
response.addCookie(cookie);
}
@@ -332,7 +339,7 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
}
/**
* Implementation of <tt>LogoutHandler</tt>. Default behaviour is to call <tt>cancelCookie()</tt>.
* Implementation of {@code LogoutHandler}. Default behaviour is to call {@code cancelCookie()}.
*/
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
if (logger.isDebugEnabled()) {
@@ -395,6 +402,15 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
return tokenValiditySeconds;
}
/**
* Whether the cookie should be flagged as secure or not. Secure cookies can only be sent over an HTTPS connection
* and this cannot be accidentally submitted over HTTP where they could be intercepted.
* <p>
* By default the cookie will be secure if the request is secure. If you only want to use remember-me over
* HTTPS (recommended) you should set this property to {@code true}.
*
* @param useSecureCookie set to {@code true} to always user secure cookies, {@code false} to disable their use.
*/
public void setUseSecureCookie(boolean useSecureCookie) {
this.useSecureCookie = useSecureCookie;
}
@@ -106,7 +106,7 @@ public class AbstractRememberMeServicesTests {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
// set non-login cookie
request.setCookies(new Cookie[] {new Cookie("mycookie", "cookie")});
request.setCookies(new Cookie("mycookie", "cookie"));
assertNull(services.autoLogin(request, response));
assertNull(response.getCookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY));
}
@@ -134,8 +134,7 @@ public class AbstractRememberMeServicesTests {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.setCookies(new Cookie[] {
new Cookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, "ZZZ")});
request.setCookies(new Cookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, "ZZZ"));
Authentication result = services.autoLogin(request, response);
assertNull(result);
assertCookieCancelled(response);
@@ -147,8 +146,7 @@ public class AbstractRememberMeServicesTests {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.setCookies(new Cookie[] {
new Cookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, "")});
request.setCookies(new Cookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, ""));
Authentication result = services.autoLogin(request, response);
assertNull(result);
assertCookieCancelled(response);