SEC-949: Added the option of specifying -1 as the token-validity-seconds value in order to set the cookie maxAge to expire when the browser closes.
This commit is contained in:
parent
c2e688610c
commit
db5f1e69f1
|
@ -98,7 +98,12 @@ public class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokenValiditySet) {
|
if (tokenValiditySet) {
|
||||||
services.getPropertyValues().addPropertyValue("tokenValiditySeconds", new Integer(tokenValiditySeconds));
|
Integer tokenValidity = new Integer(tokenValiditySeconds);
|
||||||
|
if (tokenValidity.intValue() < 0 && isPersistent) {
|
||||||
|
parserContext.getReaderContext().error(ATT_TOKEN_VALIDITY + " cannot be negative if using" +
|
||||||
|
" a persistent remember-me token repository", source);
|
||||||
|
}
|
||||||
|
services.getPropertyValues().addPropertyValue("tokenValiditySeconds", tokenValidity);
|
||||||
}
|
}
|
||||||
services.setSource(source);
|
services.setSource(source);
|
||||||
services.getPropertyValues().addPropertyValue(ATT_KEY, key);
|
services.getPropertyValues().addPropertyValue(ATT_KEY, key);
|
||||||
|
|
|
@ -36,6 +36,7 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
|
||||||
|
|
||||||
public static final String SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY = "SPRING_SECURITY_REMEMBER_ME_COOKIE";
|
public static final String SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY = "SPRING_SECURITY_REMEMBER_ME_COOKIE";
|
||||||
public static final String DEFAULT_PARAMETER = "_spring_security_remember_me";
|
public static final String DEFAULT_PARAMETER = "_spring_security_remember_me";
|
||||||
|
public static final int TWO_WEEKS_S = 1209600;
|
||||||
|
|
||||||
private static final String DELIMITER = ":";
|
private static final String DELIMITER = ":";
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
|
||||||
private String parameter = DEFAULT_PARAMETER;
|
private String parameter = DEFAULT_PARAMETER;
|
||||||
private boolean alwaysRemember;
|
private boolean alwaysRemember;
|
||||||
private String key;
|
private String key;
|
||||||
private int tokenValiditySeconds = 1209600; // 14 days
|
private int tokenValiditySeconds = TWO_WEEKS_S;
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.hasLength(key);
|
Assert.hasLength(key);
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
package org.springframework.security.ui.rememberme;
|
package org.springframework.security.ui.rememberme;
|
||||||
|
|
||||||
import org.springframework.security.Authentication;
|
|
||||||
import org.springframework.security.userdetails.UserDetails;
|
|
||||||
import org.springframework.dao.DataAccessException;
|
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.security.Authentication;
|
||||||
|
import org.springframework.security.userdetails.UserDetails;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link RememberMeServices} implementation based on Barry Jaspan's
|
* {@link RememberMeServices} implementation based on Barry Jaspan's
|
||||||
* <a href="http://jaspan.com/improved_persistent_login_cookie_best_practice">Improved Persistent Login Cookie
|
* <a href="http://jaspan.com/improved_persistent_login_cookie_best_practice">Improved Persistent Login Cookie
|
||||||
|
@ -164,4 +165,10 @@ public class PersistentTokenBasedRememberMeServices extends AbstractRememberMeSe
|
||||||
public void setTokenLength(int tokenLength) {
|
public void setTokenLength(int tokenLength) {
|
||||||
this.tokenLength = tokenLength;
|
this.tokenLength = tokenLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTokenValiditySeconds(int tokenValiditySeconds) {
|
||||||
|
Assert.isTrue(tokenValiditySeconds > 0, "tokenValiditySeconds must be positive for this implementation");
|
||||||
|
super.setTokenValiditySeconds(tokenValiditySeconds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,9 @@ import java.util.Date;
|
||||||
* require a more secure remember-me approach (see {@link PersistentTokenBasedRememberMeServices}).
|
* require a more secure remember-me approach (see {@link PersistentTokenBasedRememberMeServices}).
|
||||||
* <p>
|
* <p>
|
||||||
* By default the tokens will be valid for 14 days from the last successful authentication attempt. This can be changed
|
* By default the tokens will be valid for 14 days from the last successful authentication attempt. This can be changed
|
||||||
* using {@link #setTokenValiditySeconds(int)}.
|
* using {@link #setTokenValiditySeconds(int)}. If this value is less than zero, the <tt>expiryTime</tt> will remain at
|
||||||
|
* 14 days, but the negative value will be used for the <tt>maxAge</tt> property of the cookie, meaning that it will
|
||||||
|
* not be stored when the browser is closed.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author Ben Alex
|
* @author Ben Alex
|
||||||
|
@ -147,7 +149,9 @@ public class TokenBasedRememberMeServices extends AbstractRememberMeServices {
|
||||||
}
|
}
|
||||||
|
|
||||||
int tokenLifetime = calculateLoginLifetime(request, successfulAuthentication);
|
int tokenLifetime = calculateLoginLifetime(request, successfulAuthentication);
|
||||||
long expiryTime = System.currentTimeMillis() + 1000L*tokenLifetime;
|
long expiryTime = System.currentTimeMillis();
|
||||||
|
// SEC-949
|
||||||
|
expiryTime += 1000L* (tokenLifetime < 0 ? TWO_WEEKS_S : tokenLifetime);
|
||||||
|
|
||||||
String signatureValue = makeTokenSignature(expiryTime, username, password);
|
String signatureValue = makeTokenSignature(expiryTime, username, password);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ path-type =
|
||||||
attribute path-type {"ant" | "regex"}
|
attribute path-type {"ant" | "regex"}
|
||||||
port =
|
port =
|
||||||
## Specifies an IP port number. Used to configure an embedded LDAP server, for example.
|
## Specifies an IP port number. Used to configure an embedded LDAP server, for example.
|
||||||
attribute port { xsd:integer }
|
attribute port { xsd:positiveInteger }
|
||||||
url =
|
url =
|
||||||
## Specifies a URL.
|
## Specifies a URL.
|
||||||
attribute url { xsd:string }
|
attribute url { xsd:string }
|
||||||
|
@ -258,6 +258,10 @@ http.attlist &=
|
||||||
http.attlist &=
|
http.attlist &=
|
||||||
## Allows the access denied page to be set (the user will be redirected here if an AccessDeniedException is raised).
|
## Allows the access denied page to be set (the user will be redirected here if an AccessDeniedException is raised).
|
||||||
attribute access-denied-page {xsd:string}?
|
attribute access-denied-page {xsd:string}?
|
||||||
|
http.attlist &=
|
||||||
|
##
|
||||||
|
attribute disable-url-rewriting {boolean}?
|
||||||
|
|
||||||
|
|
||||||
intercept-url =
|
intercept-url =
|
||||||
## Specifies the access attributes and/or filter list for a particular set of URLs.
|
## Specifies the access attributes and/or filter list for a particular set of URLs.
|
||||||
|
@ -389,8 +393,8 @@ remember-me.attlist &=
|
||||||
user-service-ref?
|
user-service-ref?
|
||||||
|
|
||||||
remember-me.attlist &=
|
remember-me.attlist &=
|
||||||
## The period (in seconds) for which the remember-me cookie should be valid.
|
## The period (in seconds) for which the remember-me cookie should be valid. If set to a negative value
|
||||||
attribute token-validity-seconds {xsd:positiveInteger}?
|
attribute token-validity-seconds {xsd:integer}?
|
||||||
|
|
||||||
token-repository-ref =
|
token-repository-ref =
|
||||||
## Reference to a PersistentTokenRepository bean for use with the persistent token remember-me implementation.
|
## Reference to a PersistentTokenRepository bean for use with the persistent token remember-me implementation.
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
</xs:attributeGroup>
|
</xs:attributeGroup>
|
||||||
<xs:attributeGroup name="port">
|
<xs:attributeGroup name="port">
|
||||||
<xs:attribute name="port" use="required" type="xs:integer">
|
<xs:attribute name="port" use="required" type="xs:positiveInteger">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>Specifies an IP port number. Used to configure an embedded LDAP
|
<xs:documentation>Specifies an IP port number. Used to configure an embedded LDAP
|
||||||
server, for example.</xs:documentation>
|
server, for example.</xs:documentation>
|
||||||
|
@ -206,7 +206,7 @@
|
||||||
<xs:documentation>Specifies a URL.</xs:documentation>
|
<xs:documentation>Specifies a URL.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
<xs:attribute name="port" type="xs:integer">
|
<xs:attribute name="port" type="xs:positiveInteger">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>Specifies an IP port number. Used to configure an embedded LDAP
|
<xs:documentation>Specifies an IP port number. Used to configure an embedded LDAP
|
||||||
server, for example.</xs:documentation>
|
server, for example.</xs:documentation>
|
||||||
|
@ -890,6 +890,11 @@
|
||||||
here if an AccessDeniedException is raised).</xs:documentation>
|
here if an AccessDeniedException is raised).</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
|
<xs:attribute name="disable-url-rewriting" type="security:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation> </xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
</xs:attributeGroup>
|
</xs:attributeGroup>
|
||||||
<xs:attributeGroup name="intercept-url.attlist">
|
<xs:attributeGroup name="intercept-url.attlist">
|
||||||
<xs:attribute name="pattern" use="required" type="xs:string">
|
<xs:attribute name="pattern" use="required" type="xs:string">
|
||||||
|
@ -1187,10 +1192,10 @@
|
||||||
Id</xs:documentation>
|
Id</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
<xs:attribute name="token-validity-seconds" type="xs:positiveInteger">
|
<xs:attribute name="token-validity-seconds" type="xs:integer">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>The period (in seconds) for which the remember-me cookie should be
|
<xs:documentation>The period (in seconds) for which the remember-me cookie should be
|
||||||
valid. </xs:documentation>
|
valid. If set to a negative value</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
</xs:attributeGroup>
|
</xs:attributeGroup>
|
||||||
|
|
|
@ -370,11 +370,11 @@ public class HttpSecurityBeanDefinitionParserTests {
|
||||||
@Test
|
@Test
|
||||||
public void rememberMeServiceWorksWithTokenRepoRef() {
|
public void rememberMeServiceWorksWithTokenRepoRef() {
|
||||||
setContext(
|
setContext(
|
||||||
"<http auto-config='true'>" +
|
"<http auto-config='true'>" +
|
||||||
" <remember-me token-repository-ref='tokenRepo'/>" +
|
" <remember-me token-repository-ref='tokenRepo'/>" +
|
||||||
"</http>" +
|
"</http>" +
|
||||||
"<b:bean id='tokenRepo' " +
|
"<b:bean id='tokenRepo' " +
|
||||||
"class='org.springframework.security.ui.rememberme.InMemoryTokenRepositoryImpl'/> " + AUTH_PROVIDER_XML);
|
"class='org.springframework.security.ui.rememberme.InMemoryTokenRepositoryImpl'/> " + AUTH_PROVIDER_XML);
|
||||||
Object rememberMeServices = appContext.getBean(BeanIds.REMEMBER_ME_SERVICES);
|
Object rememberMeServices = appContext.getBean(BeanIds.REMEMBER_ME_SERVICES);
|
||||||
|
|
||||||
assertTrue(rememberMeServices instanceof PersistentTokenBasedRememberMeServices);
|
assertTrue(rememberMeServices instanceof PersistentTokenBasedRememberMeServices);
|
||||||
|
@ -394,7 +394,6 @@ public class HttpSecurityBeanDefinitionParserTests {
|
||||||
assertTrue(rememberMeServices instanceof PersistentTokenBasedRememberMeServices);
|
assertTrue(rememberMeServices instanceof PersistentTokenBasedRememberMeServices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rememberMeServiceWorksWithExternalServicesImpl() throws Exception {
|
public void rememberMeServiceWorksWithExternalServicesImpl() throws Exception {
|
||||||
setContext(
|
setContext(
|
||||||
|
@ -426,6 +425,26 @@ public class HttpSecurityBeanDefinitionParserTests {
|
||||||
"tokenValiditySeconds"));
|
"tokenValiditySeconds"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void rememberMeTokenValidityAllowsNegativeValueForNonPersistentImplementation() throws Exception {
|
||||||
|
setContext(
|
||||||
|
"<http auto-config='true'>" +
|
||||||
|
" <remember-me key='ourkey' token-validity-seconds='-1' />" +
|
||||||
|
"</http>" + AUTH_PROVIDER_XML);
|
||||||
|
assertEquals(-1, FieldUtils.getFieldValue(appContext.getBean(BeanIds.REMEMBER_ME_SERVICES),
|
||||||
|
"tokenValiditySeconds"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=BeanDefinitionParsingException.class)
|
||||||
|
public void rememberMeTokenValidityRejectsNegativeValueForPersistentImplementation() throws Exception {
|
||||||
|
setContext(
|
||||||
|
"<http auto-config='true'>" +
|
||||||
|
" <remember-me token-validity-seconds='-1' token-repository-ref='tokenRepo'/>" +
|
||||||
|
"</http>" +
|
||||||
|
"<b:bean id='tokenRepo' class='org.springframework.security.ui.rememberme.InMemoryTokenRepositoryImpl'/> " +
|
||||||
|
AUTH_PROVIDER_XML);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rememberMeServiceConfigurationParsesWithCustomUserService() {
|
public void rememberMeServiceConfigurationParsesWithCustomUserService() {
|
||||||
setContext(
|
setContext(
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.springframework.security.ui.rememberme;
|
package org.springframework.security.ui.rememberme;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import static org.springframework.security.ui.rememberme.TokenBasedRememberMeServices.*;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
@ -102,7 +103,7 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
Authentication result = services.autoLogin(new MockHttpServletRequest(), response);
|
Authentication result = services.autoLogin(new MockHttpServletRequest(), response);
|
||||||
assertNull(result);
|
assertNull(result);
|
||||||
// No cookie set
|
// No cookie set
|
||||||
assertNull(response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY));
|
assertNull(response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -115,12 +116,12 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
Authentication result = services.autoLogin(request, response);
|
Authentication result = services.autoLogin(request, response);
|
||||||
|
|
||||||
assertNull(result);
|
assertNull(result);
|
||||||
assertNull(response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY));
|
assertNull(response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void autoLoginReturnsNullForExpiredCookieAndClearsCookie() throws Exception {
|
public void autoLoginReturnsNullForExpiredCookieAndClearsCookie() throws Exception {
|
||||||
Cookie cookie = new Cookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
||||||
generateCorrectCookieContentForToken(System.currentTimeMillis() - 1000000, "someone", "password", "key"));
|
generateCorrectCookieContentForToken(System.currentTimeMillis() - 1000000, "someone", "password", "key"));
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setCookies(new Cookie[] {cookie});
|
request.setCookies(new Cookie[] {cookie});
|
||||||
|
@ -128,14 +129,14 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
||||||
assertNull(services.autoLogin(request, response));
|
assertNull(services.autoLogin(request, response));
|
||||||
Cookie returnedCookie = response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
||||||
assertNotNull(returnedCookie);
|
assertNotNull(returnedCookie);
|
||||||
assertEquals(0, returnedCookie.getMaxAge());
|
assertEquals(0, returnedCookie.getMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void autoLoginReturnsNullAndClearsCookieIfMissingThreeTokensInCookieValue() throws Exception {
|
public void autoLoginReturnsNullAndClearsCookieIfMissingThreeTokensInCookieValue() throws Exception {
|
||||||
Cookie cookie = new Cookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
||||||
new String(Base64.encodeBase64("x".getBytes())));
|
new String(Base64.encodeBase64("x".getBytes())));
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setCookies(new Cookie[] {cookie});
|
request.setCookies(new Cookie[] {cookie});
|
||||||
|
@ -143,14 +144,14 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
assertNull(services.autoLogin(request, response));
|
assertNull(services.autoLogin(request, response));
|
||||||
|
|
||||||
Cookie returnedCookie = response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
||||||
assertNotNull(returnedCookie);
|
assertNotNull(returnedCookie);
|
||||||
assertEquals(0, returnedCookie.getMaxAge());
|
assertEquals(0, returnedCookie.getMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void autoLoginClearsNonBase64EncodedCookie() throws Exception {
|
public void autoLoginClearsNonBase64EncodedCookie() throws Exception {
|
||||||
Cookie cookie = new Cookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
||||||
"NOT_BASE_64_ENCODED");
|
"NOT_BASE_64_ENCODED");
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setCookies(new Cookie[] {cookie});
|
request.setCookies(new Cookie[] {cookie});
|
||||||
|
@ -158,7 +159,7 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
assertNull(services.autoLogin(request, response));
|
assertNull(services.autoLogin(request, response));
|
||||||
|
|
||||||
Cookie returnedCookie = response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
||||||
assertNotNull(returnedCookie);
|
assertNotNull(returnedCookie);
|
||||||
assertEquals(0, returnedCookie.getMaxAge());
|
assertEquals(0, returnedCookie.getMaxAge());
|
||||||
}
|
}
|
||||||
|
@ -166,7 +167,7 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
@Test
|
@Test
|
||||||
public void autoLoginClearsCookieIfSignatureBlocksDoesNotMatchExpectedValue() throws Exception {
|
public void autoLoginClearsCookieIfSignatureBlocksDoesNotMatchExpectedValue() throws Exception {
|
||||||
jmock.checking(udsWillReturnUser);
|
jmock.checking(udsWillReturnUser);
|
||||||
Cookie cookie = new Cookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
||||||
generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password",
|
generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password",
|
||||||
"WRONG_KEY"));
|
"WRONG_KEY"));
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
@ -176,14 +177,14 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
|
|
||||||
assertNull(services.autoLogin(request, response));
|
assertNull(services.autoLogin(request, response));
|
||||||
|
|
||||||
Cookie returnedCookie = response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
||||||
assertNotNull(returnedCookie);
|
assertNotNull(returnedCookie);
|
||||||
assertEquals(0, returnedCookie.getMaxAge());
|
assertEquals(0, returnedCookie.getMaxAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void autoLoginClearsCookieIfTokenDoesNotContainANumberInCookieValue() throws Exception {
|
public void autoLoginClearsCookieIfTokenDoesNotContainANumberInCookieValue() throws Exception {
|
||||||
Cookie cookie = new Cookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
||||||
new String(Base64.encodeBase64("username:NOT_A_NUMBER:signature".getBytes())));
|
new String(Base64.encodeBase64("username:NOT_A_NUMBER:signature".getBytes())));
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setCookies(new Cookie[] {cookie});
|
request.setCookies(new Cookie[] {cookie});
|
||||||
|
@ -191,7 +192,7 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
assertNull(services.autoLogin(request, response));
|
assertNull(services.autoLogin(request, response));
|
||||||
|
|
||||||
Cookie returnedCookie = response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
||||||
assertNotNull(returnedCookie);
|
assertNotNull(returnedCookie);
|
||||||
assertEquals(0, returnedCookie.getMaxAge());
|
assertEquals(0, returnedCookie.getMaxAge());
|
||||||
}
|
}
|
||||||
|
@ -199,7 +200,7 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
@Test
|
@Test
|
||||||
public void autoLoginClearsCookieIfUserNotFound() throws Exception {
|
public void autoLoginClearsCookieIfUserNotFound() throws Exception {
|
||||||
jmock.checking(udsWillThrowNotFound);
|
jmock.checking(udsWillThrowNotFound);
|
||||||
Cookie cookie = new Cookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
||||||
generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password", "key"));
|
generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password", "key"));
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setCookies(new Cookie[] {cookie});
|
request.setCookies(new Cookie[] {cookie});
|
||||||
|
@ -208,7 +209,7 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
|
|
||||||
assertNull(services.autoLogin(request, response));
|
assertNull(services.autoLogin(request, response));
|
||||||
|
|
||||||
Cookie returnedCookie = response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
||||||
assertNotNull(returnedCookie);
|
assertNotNull(returnedCookie);
|
||||||
assertEquals(0, returnedCookie.getMaxAge());
|
assertEquals(0, returnedCookie.getMaxAge());
|
||||||
}
|
}
|
||||||
|
@ -216,7 +217,7 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
@Test
|
@Test
|
||||||
public void autoLoginWithValidTokenAndUserSucceeds() throws Exception {
|
public void autoLoginWithValidTokenAndUserSucceeds() throws Exception {
|
||||||
jmock.checking(udsWillReturnUser);
|
jmock.checking(udsWillReturnUser);
|
||||||
Cookie cookie = new Cookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
|
||||||
generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password", "key"));
|
generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password", "key"));
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setCookies(new Cookie[] {cookie});
|
request.setCookies(new Cookie[] {cookie});
|
||||||
|
@ -236,7 +237,7 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
services.setKey("d");
|
services.setKey("d");
|
||||||
assertEquals("d", services.getKey());
|
assertEquals("d", services.getKey());
|
||||||
|
|
||||||
assertEquals(TokenBasedRememberMeServices.DEFAULT_PARAMETER, services.getParameter());
|
assertEquals(DEFAULT_PARAMETER, services.getParameter());
|
||||||
services.setParameter("some_param");
|
services.setParameter("some_param");
|
||||||
assertEquals("some_param", services.getParameter());
|
assertEquals("some_param", services.getParameter());
|
||||||
|
|
||||||
|
@ -250,7 +251,7 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
services.loginFail(request, response);
|
services.loginFail(request, response);
|
||||||
|
|
||||||
Cookie cookie = response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
Cookie cookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
||||||
assertNotNull(cookie);
|
assertNotNull(cookie);
|
||||||
assertEquals(0, cookie.getMaxAge());
|
assertEquals(0, cookie.getMaxAge());
|
||||||
}
|
}
|
||||||
|
@ -259,12 +260,12 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
public void loginSuccessIgnoredIfParameterNotSetOrFalse() {
|
public void loginSuccessIgnoredIfParameterNotSetOrFalse() {
|
||||||
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
|
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.addParameter(TokenBasedRememberMeServices.DEFAULT_PARAMETER, "false");
|
request.addParameter(DEFAULT_PARAMETER, "false");
|
||||||
|
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
services.loginSuccess(request, response, new TestingAuthenticationToken("someone", "password","ROLE_ABC"));
|
services.loginSuccess(request, response, new TestingAuthenticationToken("someone", "password","ROLE_ABC"));
|
||||||
|
|
||||||
Cookie cookie = response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
Cookie cookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
||||||
assertNull(cookie);
|
assertNull(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +279,7 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
services.loginSuccess(request, response, new TestingAuthenticationToken("someone", "password","ROLE_ABC"));
|
services.loginSuccess(request, response, new TestingAuthenticationToken("someone", "password","ROLE_ABC"));
|
||||||
|
|
||||||
Cookie cookie = response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
Cookie cookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
||||||
String expiryTime = services.decodeCookie(cookie.getValue())[1];
|
String expiryTime = services.decodeCookie(cookie.getValue())[1];
|
||||||
long expectedExpiryTime = 1000L * 500000000;
|
long expectedExpiryTime = 1000L * 500000000;
|
||||||
expectedExpiryTime += System.currentTimeMillis();
|
expectedExpiryTime += System.currentTimeMillis();
|
||||||
|
@ -297,17 +298,36 @@ public class TokenBasedRememberMeServicesTests {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
services.loginSuccess(request, response, new TestingAuthenticationToken("someone", "password","ROLE_ABC"));
|
services.loginSuccess(request, response, new TestingAuthenticationToken("someone", "password","ROLE_ABC"));
|
||||||
|
|
||||||
Cookie cookie = response.getCookie(TokenBasedRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
Cookie cookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
||||||
assertNotNull(cookie);
|
assertNotNull(cookie);
|
||||||
assertEquals(services.getTokenValiditySeconds(), cookie.getMaxAge());
|
assertEquals(services.getTokenValiditySeconds(), cookie.getMaxAge());
|
||||||
assertTrue(Base64.isArrayByteBase64(cookie.getValue().getBytes()));
|
assertTrue(Base64.isArrayByteBase64(cookie.getValue().getBytes()));
|
||||||
assertTrue(new Date().before(new Date(determineExpiryTimeFromBased64EncodedToken(cookie.getValue()))));
|
assertTrue(new Date().before(new Date(determineExpiryTimeFromBased64EncodedToken(cookie.getValue()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// SEC-933
|
// SEC-933
|
||||||
@Test
|
@Test
|
||||||
public void obtainPasswordReturnsNullForTokenWithNullCredentials() throws Exception {
|
public void obtainPasswordReturnsNullForTokenWithNullCredentials() throws Exception {
|
||||||
TestingAuthenticationToken token = new TestingAuthenticationToken("username", null);
|
TestingAuthenticationToken token = new TestingAuthenticationToken("username", null);
|
||||||
assertNull(services.retrievePassword(token));
|
assertNull(services.retrievePassword(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SEC-949
|
||||||
|
@Test
|
||||||
|
public void negativeValidityPeriodIsSetOnCookieButExpiryTimeRemainsAtTwoWeeks() throws Exception {
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addParameter(DEFAULT_PARAMETER, "true");
|
||||||
|
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
services.setTokenValiditySeconds(-1);
|
||||||
|
services.loginSuccess(request, response, new TestingAuthenticationToken("someone", "password","ROLE_ABC"));
|
||||||
|
|
||||||
|
Cookie cookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
|
||||||
|
assertNotNull(cookie);
|
||||||
|
// Check the expiry time is within 50ms of two weeks from current time
|
||||||
|
assertTrue(determineExpiryTimeFromBased64EncodedToken(cookie.getValue()) - System.currentTimeMillis() >
|
||||||
|
TWO_WEEKS_S - 50);
|
||||||
|
assertEquals(-1, cookie.getMaxAge());
|
||||||
|
assertTrue(Base64.isArrayByteBase64(cookie.getValue().getBytes()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue