Added remember-me services.

This commit is contained in:
Ben Alex
2005-03-01 02:30:38 +00:00
parent 0d33b06990
commit f1e071b0f1
28 changed files with 2098 additions and 21 deletions

View File

@@ -19,6 +19,7 @@ import junit.framework.TestCase;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import net.sf.acegisecurity.providers.anonymous.AnonymousAuthenticationToken;
import net.sf.acegisecurity.providers.rememberme.RememberMeAuthenticationToken;
/**
@@ -54,6 +55,16 @@ public class AuthenticationTrustResolverImplTests extends TestCase {
new GrantedAuthority[] {new GrantedAuthorityImpl("ignored")})));
}
public void testCorrectOperationIsRememberMe() {
AuthenticationTrustResolverImpl trustResolver = new AuthenticationTrustResolverImpl();
assertTrue(trustResolver.isRememberMe(
new RememberMeAuthenticationToken("ignored", "ignored",
new GrantedAuthority[] {new GrantedAuthorityImpl("ignored")})));
assertFalse(trustResolver.isAnonymous(
new TestingAuthenticationToken("ignored", "ignored",
new GrantedAuthority[] {new GrantedAuthorityImpl("ignored")})));
}
public void testGettersSetters() {
AuthenticationTrustResolverImpl trustResolver = new AuthenticationTrustResolverImpl();
@@ -62,6 +73,9 @@ public class AuthenticationTrustResolverImplTests extends TestCase {
trustResolver.setAnonymousClass(String.class);
assertEquals(String.class, trustResolver.getAnonymousClass());
assertNull(trustResolver.getRememberMeClass());
assertEquals(RememberMeAuthenticationToken.class,
trustResolver.getRememberMeClass());
trustResolver.setRememberMeClass(String.class);
assertEquals(String.class, trustResolver.getRememberMeClass());
}
}

View File

@@ -54,6 +54,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
private Map attribMap = new HashMap();
private Map headersMap = new HashMap();
private Map paramMap = new HashMap();
private Map cookiesMap = new HashMap();
private Principal principal;
private String contextPath = "";
private String pathInfo; // null for no extra path
@@ -75,6 +76,15 @@ public class MockHttpServletRequest implements HttpServletRequest {
this.queryString = queryString;
}
public MockHttpServletRequest(Map headers, HttpSession session, String queryString, Cookie[] cookies) {
this.queryString = queryString;
this.headersMap = headers;
this.session = session;
for (int i = 0; i < cookies.length; i++) {
cookiesMap.put(cookies[i].getName(), cookies[i]);
}
}
public MockHttpServletRequest(Map headers, Principal principal,
HttpSession session) {
this.headersMap = headers;
@@ -129,7 +139,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
public Cookie[] getCookies() {
throw new UnsupportedOperationException("mock method not implemented");
return (Cookie[]) cookiesMap.values().toArray(new Cookie[] {});
}
public long getDateHeader(String arg0) {

View File

@@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,6 +37,7 @@ import javax.servlet.http.HttpServletResponse;
public class MockHttpServletResponse implements HttpServletResponse {
//~ Instance fields ========================================================
private Map cookiesMap = new HashMap();
private Map headersMap = new HashMap();
private String errorMessage;
private String redirect;
@@ -72,6 +73,10 @@ public class MockHttpServletResponse implements HttpServletResponse {
throw new UnsupportedOperationException("mock method not implemented");
}
public Cookie getCookieByName(String name) {
return (Cookie) cookiesMap.get(name);
}
public void setDateHeader(String arg0, long arg1) {
throw new UnsupportedOperationException("mock method not implemented");
}
@@ -131,7 +136,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
}
public void addCookie(Cookie arg0) {
throw new UnsupportedOperationException("mock method not implemented");
cookiesMap.put(arg0.getName(), arg0);
}
public void addDateHeader(String arg0, long arg1) {

View File

@@ -0,0 +1,122 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed 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 net.sf.acegisecurity.providers.rememberme;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.BadCredentialsException;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
/**
* Tests {@link RememberMeAuthenticationProvider}.
*
* @author Ben Alex
* @version $Id$
*/
public class RememberMeAuthenticationProviderTests extends TestCase {
//~ Constructors ===========================================================
public RememberMeAuthenticationProviderTests() {
super();
}
public RememberMeAuthenticationProviderTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
}
public static void main(String[] args) {
junit.textui.TestRunner.run(RememberMeAuthenticationProviderTests.class);
}
public void testDetectsAnInvalidKey() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
aap.setKey("qwerty");
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("WRONG_KEY",
"Test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
try {
Authentication result = aap.authenticate(token);
fail("Should have thrown BadCredentialsException");
} catch (BadCredentialsException expected) {
assertEquals("The presented RememberMeAuthenticationToken does not contain the expected key",
expected.getMessage());
}
}
public void testDetectsMissingKey() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
try {
aap.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testGettersSetters() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
aap.setKey("qwerty");
aap.afterPropertiesSet();
assertEquals("qwerty", aap.getKey());
}
public void testIgnoresClassesItDoesNotSupport() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
aap.setKey("qwerty");
TestingAuthenticationToken token = new TestingAuthenticationToken("user",
"password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")});
assertFalse(aap.supports(TestingAuthenticationToken.class));
// Try it anyway
assertNull(aap.authenticate(token));
}
public void testNormalOperation() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
aap.setKey("qwerty");
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("qwerty",
"Test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
Authentication result = aap.authenticate(token);
assertEquals(result, token);
}
public void testSupports() {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
assertTrue(aap.supports(RememberMeAuthenticationToken.class));
assertFalse(aap.supports(TestingAuthenticationToken.class));
}
}

View File

@@ -0,0 +1,190 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed 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 net.sf.acegisecurity.providers.rememberme;
import junit.framework.TestCase;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import java.util.List;
import java.util.Vector;
/**
* Tests {@link RememberMeAuthenticationToken}.
*
* @author Ben Alex
* @version $Id$
*/
public class RememberMeAuthenticationTokenTests extends TestCase {
//~ Constructors ===========================================================
public RememberMeAuthenticationTokenTests() {
super();
}
public RememberMeAuthenticationTokenTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
}
public static void main(String[] args) {
junit.textui.TestRunner.run(RememberMeAuthenticationTokenTests.class);
}
public void testConstructorRejectsNulls() {
try {
new RememberMeAuthenticationToken(null, "Test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new RememberMeAuthenticationToken("key", null,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new RememberMeAuthenticationToken("key", "Test", null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new RememberMeAuthenticationToken("key", "Test",
new GrantedAuthority[] {null});
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new RememberMeAuthenticationToken("key", "Test",
new GrantedAuthority[] {});
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testEqualsWhenEqual() {
List proxyList1 = new Vector();
proxyList1.add("https://localhost/newPortal/j_acegi_cas_security_check");
RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key",
"Test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
RememberMeAuthenticationToken token2 = new RememberMeAuthenticationToken("key",
"Test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
assertEquals(token1, token2);
}
public void testGetters() {
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("key",
"Test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
assertEquals("key".hashCode(), token.getKeyHash());
assertEquals("Test", token.getPrincipal());
assertEquals("", token.getCredentials());
assertEquals("ROLE_ONE", token.getAuthorities()[0].getAuthority());
assertEquals("ROLE_TWO", token.getAuthorities()[1].getAuthority());
assertTrue(token.isAuthenticated());
}
public void testNoArgConstructor() {
try {
new RememberMeAuthenticationToken();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testNotEqualsDueToAbstractParentEqualsCheck() {
RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key",
"Test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
RememberMeAuthenticationToken token2 = new RememberMeAuthenticationToken("key",
"DIFFERENT_PRINCIPAL",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
assertFalse(token1.equals(token2));
}
public void testNotEqualsDueToDifferentAuthenticationClass() {
RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key",
"Test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
UsernamePasswordAuthenticationToken token2 = new UsernamePasswordAuthenticationToken("Test",
"Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
token2.setAuthenticated(true);
assertFalse(token1.equals(token2));
}
public void testNotEqualsDueToKey() {
RememberMeAuthenticationToken token1 = new RememberMeAuthenticationToken("key",
"Test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
RememberMeAuthenticationToken token2 = new RememberMeAuthenticationToken("DIFFERENT_KEY",
"Test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
assertFalse(token1.equals(token2));
}
public void testSetAuthenticatedIgnored() {
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("key",
"Test",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")});
assertTrue(token.isAuthenticated());
token.setAuthenticated(false); // ignored
assertTrue(token.isAuthenticated());
}
}

View File

@@ -30,6 +30,7 @@ import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextUtils;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.ui.rememberme.TokenBasedRememberMeServices;
import java.io.IOException;
@@ -150,6 +151,11 @@ public class AbstractProcessingFilterTests extends TestCase {
public void testGettersSetters() {
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
assertNotNull(filter.getRememberMeServices());
filter.setRememberMeServices(new TokenBasedRememberMeServices());
assertEquals(TokenBasedRememberMeServices.class,
filter.getRememberMeServices().getClass());
filter.setAuthenticationFailureUrl("/x");
assertEquals("/x", filter.getAuthenticationFailureUrl());

View File

@@ -0,0 +1,51 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed 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 net.sf.acegisecurity.ui.rememberme;
import junit.framework.TestCase;
/**
* Tests {@link net.sf.acegisecurity.ui.rememberme.NullRememberMeServices}.
*
* @author Ben Alex
* @version $Id$
*/
public class NullRememberMeServicesTests extends TestCase {
//~ Constructors ===========================================================
public NullRememberMeServicesTests() {
super();
}
public NullRememberMeServicesTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(NullRememberMeServicesTests.class);
}
public void testAlwaysReturnsNull() {
NullRememberMeServices services = new NullRememberMeServices();
assertNull(services.autoLogin(null,null));
services.loginFail(null,null);
services.loginSuccess(null,null,null);
assertTrue(true);
}
}

View File

@@ -0,0 +1,223 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed 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 net.sf.acegisecurity.ui.rememberme;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextUtils;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
/**
* Tests {@link RememberMeProcessingFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class RememberMeProcessingFilterTests extends TestCase {
//~ Constructors ===========================================================
public RememberMeProcessingFilterTests() {
super();
}
public RememberMeProcessingFilterTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(RememberMeProcessingFilterTests.class);
}
public void testDoFilterWithNonHttpServletRequestDetected()
throws Exception {
RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
try {
filter.doFilter(null, new MockHttpServletResponse(),
new MockFilterChain());
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("Can only process HttpServletRequest",
expected.getMessage());
}
}
public void testDoFilterWithNonHttpServletResponseDetected()
throws Exception {
RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
try {
filter.doFilter(new MockHttpServletRequest("dc"), null,
new MockFilterChain());
fail("Should have thrown ServletException");
} catch (ServletException expected) {
assertEquals("Can only process HttpServletResponse",
expected.getMessage());
}
}
public void testDetectsRememberMeServicesProperty() throws Exception {
RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
// check default is NullRememberMeServices
assertEquals(NullRememberMeServices.class, filter.getRememberMeServices().getClass());
// check getter/setter
filter.setRememberMeServices(new TokenBasedRememberMeServices());
assertEquals(TokenBasedRememberMeServices.class, filter.getRememberMeServices().getClass());
// check detects if made null
filter.setRememberMeServices(null);
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testOperationWhenAuthenticationExistsInContextHolder()
throws Exception {
// Put an Authentication object into the ContextHolder
SecureContext sc = SecureContextUtils.getSecureContext();
Authentication originalAuth = new TestingAuthenticationToken("user",
"password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")});
sc.setAuthentication(originalAuth);
ContextHolder.setContext(sc);
// Setup our filter correctly
Authentication remembered = new TestingAuthenticationToken("remembered",
"password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_REMEMBERED")});
RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
filter.setRememberMeServices(new MockRememberMeServices(remembered));
filter.afterPropertiesSet();
// Test
executeFilterInContainerSimulator(new MockFilterConfig(), filter,
new MockHttpServletRequest("x"), new MockHttpServletResponse(),
new MockFilterChain(true));
// Ensure filter didn't change our original object
assertEquals(originalAuth,
SecureContextUtils.getSecureContext().getAuthentication());
}
public void testOperationWhenNoAuthenticationInContextHolder()
throws Exception {
Authentication remembered = new TestingAuthenticationToken("remembered",
"password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_REMEMBERED")});
RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
filter.setRememberMeServices(new MockRememberMeServices(remembered));
filter.afterPropertiesSet();
executeFilterInContainerSimulator(new MockFilterConfig(), filter,
new MockHttpServletRequest("x"), new MockHttpServletResponse(),
new MockFilterChain(true));
Authentication auth = SecureContextUtils.getSecureContext()
.getAuthentication();
// Ensure filter setup with our remembered authentication object
assertEquals(remembered,
SecureContextUtils.getSecureContext().getAuthentication());
}
protected void setUp() throws Exception {
super.setUp();
ContextHolder.setContext(new SecureContextImpl());
}
protected void tearDown() throws Exception {
super.tearDown();
ContextHolder.setContext(null);
}
private void executeFilterInContainerSimulator(FilterConfig filterConfig,
Filter filter, ServletRequest request, ServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
filter.init(filterConfig);
filter.doFilter(request, response, filterChain);
filter.destroy();
}
//~ Inner Classes ==========================================================
private class MockFilterChain implements FilterChain {
private boolean expectToProceed;
public MockFilterChain(boolean expectToProceed) {
this.expectToProceed = expectToProceed;
}
private MockFilterChain() {
super();
}
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (expectToProceed) {
assertTrue(true);
} else {
fail("Did not expect filter chain to proceed");
}
}
}
private class MockRememberMeServices implements RememberMeServices
{
private Authentication authToReturn;
public MockRememberMeServices(Authentication authToReturn) {
this.authToReturn = authToReturn;
}
public Authentication autoLogin(HttpServletRequest request,
HttpServletResponse response) {
return authToReturn;
}
public void loginFail(HttpServletRequest request,
HttpServletResponse response) {
}
public void loginSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication successfulAuthentication) {
}
}
}

View File

@@ -0,0 +1,412 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed 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 net.sf.acegisecurity.ui.rememberme;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import net.sf.acegisecurity.providers.dao.AuthenticationDao;
import net.sf.acegisecurity.providers.dao.User;
import net.sf.acegisecurity.providers.dao.UsernameNotFoundException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.util.StringUtils;
import java.util.Date;
import javax.servlet.http.Cookie;
/**
* Tests {@link
* net.sf.acegisecurity.ui.rememberme.TokenBasedRememberMeServices}.
*
* @author Ben Alex
* @version $Id$
*/
public class TokenBasedRememberMeServicesTests extends TestCase {
//~ Constructors ===========================================================
public TokenBasedRememberMeServicesTests() {
super();
}
public TokenBasedRememberMeServicesTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(TokenBasedRememberMeServicesTests.class);
}
public void testAutoLoginIfDoesNotPresentAnyCookies()
throws Exception {
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
services.setKey("key");
services.setAuthenticationDao(new MockAuthenticationDao(null, true));
services.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest("dc");
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
Cookie returnedCookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNull(returnedCookie); // shouldn't try to invalidate our cookie
}
public void testAutoLoginIfDoesNotPresentRequiredCookie()
throws Exception {
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
services.setKey("key");
services.setAuthenticationDao(new MockAuthenticationDao(null, true));
services.afterPropertiesSet();
Cookie cookie = new Cookie("unrelated_cookie", "foobar");
MockHttpServletRequest request = new MockHttpServletRequest(null, null,
"null", new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
Cookie returnedCookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNull(returnedCookie); // shouldn't try to invalidate our cookie
}
public void testAutoLoginIfExpired() throws Exception {
UserDetails user = new User("someone", "password", true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")});
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
services.setKey("key");
services.setAuthenticationDao(new MockAuthenticationDao(user, false));
services.afterPropertiesSet();
Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY,
generateCorrectCookieContentForToken(System.currentTimeMillis()
- 1000000, "someone", "password", "key"));
MockHttpServletRequest request = new MockHttpServletRequest(null, null,
"null", new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
Cookie returnedCookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
public void testAutoLoginIfMissingThreeTokensInCookieValue()
throws Exception {
UserDetails user = new User("someone", "password", true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")});
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
services.setKey("key");
services.setAuthenticationDao(new MockAuthenticationDao(user, false));
services.afterPropertiesSet();
Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY,
new String(Base64.encodeBase64("x".getBytes())));
MockHttpServletRequest request = new MockHttpServletRequest(null, null,
"null", new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
Cookie returnedCookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
public void testAutoLoginIfNotBase64Encoded() throws Exception {
UserDetails user = new User("someone", "password", true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")});
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
services.setKey("key");
services.setAuthenticationDao(new MockAuthenticationDao(user, false));
services.afterPropertiesSet();
Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY,
"NOT_BASE_64_ENCODED");
MockHttpServletRequest request = new MockHttpServletRequest(null, null,
"null", new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
Cookie returnedCookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
public void testAutoLoginIfSignatureBlocksDoesNotMatchExpectedValue()
throws Exception {
UserDetails user = new User("someone", "password", true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")});
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
services.setKey("key");
services.setAuthenticationDao(new MockAuthenticationDao(user, false));
services.afterPropertiesSet();
Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY,
generateCorrectCookieContentForToken(System.currentTimeMillis()
+ 1000000, "someone", "password", "WRONG_KEY"));
MockHttpServletRequest request = new MockHttpServletRequest(null, null,
"null", new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
Cookie returnedCookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
public void testAutoLoginIfTokenDoesNotContainANumberInCookieValue()
throws Exception {
UserDetails user = new User("someone", "password", true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")});
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
services.setKey("key");
services.setAuthenticationDao(new MockAuthenticationDao(user, false));
services.afterPropertiesSet();
Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY,
new String(Base64.encodeBase64(
"username:NOT_A_NUMBER:signature".getBytes())));
MockHttpServletRequest request = new MockHttpServletRequest(null, null,
"null", new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
Cookie returnedCookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
public void testAutoLoginIfUserNotFound() throws Exception {
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
services.setKey("key");
services.setAuthenticationDao(new MockAuthenticationDao(null, true));
services.afterPropertiesSet();
Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY,
generateCorrectCookieContentForToken(System.currentTimeMillis()
+ 1000000, "someone", "password", "key"));
MockHttpServletRequest request = new MockHttpServletRequest(null, null,
"null", new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
Cookie returnedCookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
public void testAutoLoginWithValidToken() throws Exception {
UserDetails user = new User("someone", "password", true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")});
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
services.setKey("key");
services.setAuthenticationDao(new MockAuthenticationDao(user, false));
services.afterPropertiesSet();
Cookie cookie = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY,
generateCorrectCookieContentForToken(System.currentTimeMillis()
+ 1000000, "someone", "password", "key"));
MockHttpServletRequest request = new MockHttpServletRequest(null, null,
"null", new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNotNull(result);
UserDetails resultingUserDetails = (UserDetails) result.getPrincipal();
assertEquals(user, resultingUserDetails);
}
public void testGettersSetters() {
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
services.setAuthenticationDao(new MockAuthenticationDao(null, false));
assertTrue(services.getAuthenticationDao() != null);
services.setKey("d");
assertEquals("d", services.getKey());
assertEquals(TokenBasedRememberMeServices.DEFAULT_PARAMETER,
services.getParameter());
services.setParameter("some_param");
assertEquals("some_param", services.getParameter());
services.setTokenValiditySeconds(12);
assertEquals(12, services.getTokenValiditySeconds());
}
public void testLoginFail() {
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
MockHttpServletRequest request = new MockHttpServletRequest("fv");
MockHttpServletResponse response = new MockHttpServletResponse();
services.loginFail(request, response);
Cookie cookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNotNull(cookie);
assertEquals(0, cookie.getMaxAge());
}
public void testLoginSuccessIgnoredIfParameterNotSetOrFalse() {
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
MockHttpServletRequest request = new MockHttpServletRequest("d");
request.setParameter(TokenBasedRememberMeServices.DEFAULT_PARAMETER,
"false");
MockHttpServletResponse response = new MockHttpServletResponse();
services.loginSuccess(request, response,
new TestingAuthenticationToken("someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")}));
Cookie cookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNull(cookie);
}
public void testLoginSuccessNormalWithNonUserDetailsBasedPrincipal() {
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
MockHttpServletRequest request = new MockHttpServletRequest("d");
request.setParameter(TokenBasedRememberMeServices.DEFAULT_PARAMETER,
"true");
MockHttpServletResponse response = new MockHttpServletResponse();
services.loginSuccess(request, response,
new TestingAuthenticationToken("someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")}));
Cookie cookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNotNull(cookie);
assertEquals(60 * 60 * 24 * 365 * 5, cookie.getMaxAge()); // 5 years
assertTrue(Base64.isArrayByteBase64(cookie.getValue().getBytes()));
assertTrue(new Date().before(
new Date(determineExpiryTimeFromBased64EncodedToken(
cookie.getValue()))));
}
public void testLoginSuccessNormalWithUserDetailsBasedPrincipal() {
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
MockHttpServletRequest request = new MockHttpServletRequest("d");
request.setParameter(TokenBasedRememberMeServices.DEFAULT_PARAMETER,
"true");
MockHttpServletResponse response = new MockHttpServletResponse();
UserDetails user = new User("someone", "password", true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")});
services.loginSuccess(request, response,
new TestingAuthenticationToken(user, "ignored",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ABC")}));
Cookie cookie = response.getCookieByName(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY);
assertNotNull(cookie);
assertEquals(60 * 60 * 24 * 365 * 5, cookie.getMaxAge()); // 5 years
assertTrue(Base64.isArrayByteBase64(cookie.getValue().getBytes()));
assertTrue(new Date().before(
new Date(determineExpiryTimeFromBased64EncodedToken(
cookie.getValue()))));
}
private long determineExpiryTimeFromBased64EncodedToken(String validToken) {
String cookieAsPlainText = new String(Base64.decodeBase64(
validToken.getBytes()));
String[] cookieTokens = StringUtils.delimitedListToStringArray(cookieAsPlainText,
":");
if (cookieTokens.length == 3) {
try {
return new Long(cookieTokens[1]).longValue();
} catch (NumberFormatException nfe) {}
}
return -1;
}
private String generateCorrectCookieContentForToken(long expiryTime,
String username, String password, String key) {
// format is:
// username + ":" + expiryTime + ":" + Md5Hex(username + ":" + expiryTime + ":" + password + ":" + key)
String signatureValue = new String(DigestUtils.md5Hex(username + ":"
+ expiryTime + ":" + password + ":" + key));
String tokenValue = username + ":" + expiryTime + ":" + signatureValue;
String tokenValueBase64 = new String(Base64.encodeBase64(
tokenValue.getBytes()));
return tokenValueBase64;
}
//~ Inner Classes ==========================================================
private class MockAuthenticationDao implements AuthenticationDao {
private UserDetails toReturn;
private boolean throwException;
public MockAuthenticationDao(UserDetails toReturn,
boolean throwException) {
this.toReturn = toReturn;
this.throwException = throwException;
}
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
if (throwException) {
throw new UsernameNotFoundException("as requested by mock");
}
return toReturn;
}
}
}