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:
parent
396eced291
commit
6e91786f92
|
@ -537,7 +537,7 @@ remember-me.attlist &=
|
|||
attribute services-alias {xsd:token}?
|
||||
|
||||
remember-me.attlist &=
|
||||
## Determines whether the "secure" flag will be set on the remember-me cookie. If set to true, the cookie will only be submitted over HTTPS. Defaults to false.
|
||||
## Determines whether the "secure" flag will be set on the remember-me cookie. If set to true, the cookie will only be submitted over HTTPS (recommended). By default, secure cookies will be used if the request is made on a secure connection.
|
||||
attribute use-secure-cookie {xsd:boolean}?
|
||||
|
||||
remember-me.attlist &=
|
||||
|
|
|
@ -1172,7 +1172,7 @@
|
|||
</xs:attribute>
|
||||
<xs:attribute name="use-secure-cookie" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Determines whether the "secure" flag will be set on the remember-me cookie. If set to true, the cookie will only be submitted over HTTPS. Defaults to false.</xs:documentation>
|
||||
<xs:documentation>Determines whether the "secure" flag will be set on the remember-me cookie. If set to true, the cookie will only be submitted over HTTPS (recommended). By default, secure cookies will be used if the request is made on a secure connection.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="token-validity-seconds" type="xs:integer">
|
||||
|
|
|
@ -72,9 +72,9 @@
|
|||
</section>
|
||||
<section xml:id="nsa-jaas-api-provision">
|
||||
<title><literal>jaas-api-provision</literal></title>
|
||||
<para>If available, runs the request as the <literal>Subject</literal> acquired from
|
||||
the <classname>JaasAuthenticationToken</classname> which is implemented by
|
||||
adding a <classname>JaasApiIntegrationFilter</classname> bean to the stack.
|
||||
<para>If available, runs the request as the <literal>Subject</literal> acquired from
|
||||
the <classname>JaasAuthenticationToken</classname> which is implemented by
|
||||
adding a <classname>JaasApiIntegrationFilter</classname> bean to the stack.
|
||||
Defaults to "false".</para>
|
||||
</section>
|
||||
<section xml:id="nsa-path-type">
|
||||
|
@ -334,7 +334,7 @@
|
|||
<para> Allows complete control of the
|
||||
<interfacename>RememberMeServices</interfacename> implementation that will be
|
||||
used by the filter. The value should be the <literal>id</literal> of a bean in the application
|
||||
context which implements this interface. Should also implement
|
||||
context which implements this interface. Should also implement
|
||||
<interfacename>LogoutHandler</interfacename> if a logout filter is in use.</para>
|
||||
</section>
|
||||
<section>
|
||||
|
@ -369,6 +369,17 @@
|
|||
and used automatically by the namespace configuration. If there are multiple
|
||||
instances, you can specify a bean <literal>id</literal> explicitly using this attribute. </para>
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>use-secure-cookie</literal></title>
|
||||
<para>It is recommended that remember-me cookies are only submitted over HTTPS and thus should
|
||||
be flagged as <quote>secure</quote>. By default, a secure cookie will be used if the
|
||||
connection over which the login request is made is secure (as it should be).
|
||||
If you set this property to <literal>false</literal>, secure cookies will not be used.
|
||||
Setting it to <literal>true</literal> will always set the secure flag on the cookie.
|
||||
This attribute maps to the <literal>useSecureCookie</literal> property of
|
||||
<classname>AbstractRememberMeServices</classname>.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>authentication-success-handler-ref</literal></title>
|
||||
<para>Sets the <code>authenticationSuccessHandler</code> property on the
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue