Refactor Authentication.isAuthenticated() handling to be more performance (as per developer list discussion).

This commit is contained in:
Ben Alex 2005-06-22 06:30:46 +00:00
parent 1e12e51b9c
commit 5f75e9bf9a
16 changed files with 211 additions and 154 deletions

View File

@ -39,16 +39,55 @@ import java.security.Principal;
public interface Authentication extends Principal, Serializable { public interface Authentication extends Principal, Serializable {
//~ Methods ================================================================ //~ Methods ================================================================
public void setAuthenticated(boolean isAuthenticated); /**
* See {@link #isAuthenticated()} for a full description.
*
* <p>
* Implementations should <b>always</b> allow this method to be called with
* a <code>false</code> parameter, as this is used by various classes to
* specify the authentication token should not be trusted. If an
* implementation wishes to reject an invocation with a <code>true</code>
* parameter (which would indicate the authentication token is trusted - a
* potential security risk) the implementation should throw an {@link
* IllegalArgumentException}.
* </p>
*
* @param isAuthenticated <code>true</code> if the token should be trusted
* (which may result in an exception) or <code>false</code> if the
* token should not be trusted
*
* @throws IllegalArgumentException if an attempt to make the
* authentication token trusted (by passing <code>true</code> as
* the argument) is rejected due to the implementation being
* immutable or implementing its own alternative approach to
* {@link #isAuthenticated()}
*/
public void setAuthenticated(boolean isAuthenticated)
throws IllegalArgumentException;
/** /**
* Indicates whether or not authentication was attempted by the {@link * Used to indicate to <code>AbstractSecurityInterceptor</code> whether it
* net.sf.acegisecurity.intercept.AbstractSecurityInterceptor}. Note that * should present the authentication token to the
* classes should not rely on this value as being valid unless it has been * <code>AuthenticationManager</code>. Typically an
* set by a trusted <code>AbstractSecurityInterceptor</code>. * <code>AuthenticationManager</code> (or, more often, one of its
* <code>AuthenticationProvider</code>s) will return an immutable
* authentication token after successful authentication, in which case
* that token can safely return <code>true</code> to this method.
* Returning <code>true</code> will improve performance, as calling the
* <code>AuthenticationManager</code> for every request will no longer be
* necessary.
*
* <p>
* For security reasons, implementations of this interface should be very
* careful about returning <code>true</code> to this method unless they
* are either immutable, or have some way of ensuring the properties have
* not been changed since original creation.
* </p>
* *
* @return true if authenticated by the * @return true if the token has been authenticated and the
* <code>AbstractSecurityInterceptor</code> * <code>AbstractSecurityInterceptor</code> does not need to
* represent the token for re-authentication to the
* <code>AuthenticationManager</code>
*/ */
public boolean isAuthenticated(); public boolean isAuthenticated();

View File

@ -82,6 +82,15 @@ public class ContextPropagatingRemoteInvocation extends RemoteInvocation {
/** /**
* Invoked on the server-side as described in the class JavaDocs. * Invoked on the server-side as described in the class JavaDocs.
*
* <p>
* Invocations will always have their {@link
* net.sf.acegisecurity.Authentication#setAuthenticated(boolean)} set to
* <code>false</code>, which is guaranteed to always be accepted by
* <code>Authentication</code> implementations. This ensures that even
* remotely authenticated <code>Authentication</code>s will be untrusted
* by the server-side, which is an appropriate security measure.
* </p>
* *
* @param targetObject the target object to apply the invocation to * @param targetObject the target object to apply the invocation to
* *
@ -97,6 +106,12 @@ public class ContextPropagatingRemoteInvocation extends RemoteInvocation {
InvocationTargetException { InvocationTargetException {
SecurityContextHolder.setContext(securityContext); SecurityContextHolder.setContext(securityContext);
if ((SecurityContextHolder.getContext() != null)
&& (SecurityContextHolder.getContext().getAuthentication() != null)) {
SecurityContextHolder.getContext().getAuthentication()
.setAuthenticated(false);
}
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Set SecurityContextHolder to contain: " logger.debug("Set SecurityContextHolder to contain: "
+ securityContext); + securityContext);

View File

@ -364,30 +364,42 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
object, attr); object, attr);
} }
// Attempt authentication // Attempt authentication if not already authenticated
Authentication authenticated; Authentication authenticated;
try { if (!SecurityContextHolder.getContext().getAuthentication()
authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext() .isAuthenticated()) {
.getAuthentication()); try {
} catch (AuthenticationException authenticationException) { authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext()
AuthenticationFailureEvent event = new AuthenticationFailureEvent(object, .getAuthentication());
attr, } catch (AuthenticationException authenticationException) {
SecurityContextHolder.getContext().getAuthentication(), AuthenticationFailureEvent event = new AuthenticationFailureEvent(object,
authenticationException); attr,
this.context.publishEvent(event); SecurityContextHolder.getContext()
.getAuthentication(),
authenticationException);
this.context.publishEvent(event);
throw authenticationException; throw authenticationException;
}
// We don't authenticated.setAuthentication(true), because each provider should do that
if (logger.isDebugEnabled()) {
logger.debug("Successfully Authenticated: "
+ authenticated.toString());
}
SecurityContextHolder.getContext().setAuthentication(authenticated);
} else {
authenticated = SecurityContextHolder.getContext()
.getAuthentication();
if (logger.isDebugEnabled()) {
logger.debug("Previously Authenticated: "
+ authenticated.toString());
}
} }
authenticated.setAuthenticated(true);
if (logger.isDebugEnabled()) {
logger.debug("Authenticated: " + authenticated.toString());
}
SecurityContextHolder.getContext().setAuthentication(authenticated);
// Attempt authorization // Attempt authorization
try { try {
this.accessDecisionManager.decide(authenticated, object, attr); this.accessDecisionManager.decide(authenticated, object, attr);

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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,21 +40,42 @@ public class UsernamePasswordAuthenticationToken
private Object details = null; private Object details = null;
private Object principal; private Object principal;
private GrantedAuthority[] authorities; private GrantedAuthority[] authorities;
private boolean authenticated = false; private boolean authenticated;
//~ Constructors =========================================================== //~ Constructors ===========================================================
/**
* This constructor can be safely used by any code that wishes to create a
* <code>UsernamePasswordAuthenticationToken</code>, as the {@link
* #isAuthenticated()} will return <code>false</code>.
*
* @param principal DOCUMENT ME!
* @param credentials DOCUMENT ME!
*/
public UsernamePasswordAuthenticationToken(Object principal, public UsernamePasswordAuthenticationToken(Object principal,
Object credentials) { Object credentials) {
this.principal = principal; this.principal = principal;
this.credentials = credentials; this.credentials = credentials;
this.authenticated = false;
} }
/**
* This constructor should only be used by
* <code>AuthenticationManager</code> or
* <code>AuthenticationProvider</code> implementations that are satisfied
* with producing a trusted (ie {@link #isAuthenticated()} =
* <code>true</code>) authentication token.
*
* @param principal
* @param credentials
* @param authorities
*/
public UsernamePasswordAuthenticationToken(Object principal, public UsernamePasswordAuthenticationToken(Object principal,
Object credentials, GrantedAuthority[] authorities) { Object credentials, GrantedAuthority[] authorities) {
this.principal = principal; this.principal = principal;
this.credentials = credentials; this.credentials = credentials;
this.authorities = authorities; this.authorities = authorities;
this.authenticated = true;
} }
protected UsernamePasswordAuthenticationToken() { protected UsernamePasswordAuthenticationToken() {
@ -63,7 +84,13 @@ public class UsernamePasswordAuthenticationToken
//~ Methods ================================================================ //~ Methods ================================================================
public void setAuthenticated(boolean isAuthenticated) { public void setAuthenticated(boolean isAuthenticated)
throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException(
"Cannot set this token to trusted - use constructor containing GrantedAuthority[]s instead");
}
this.authenticated = isAuthenticated; this.authenticated = isAuthenticated;
} }
@ -71,18 +98,6 @@ public class UsernamePasswordAuthenticationToken
return this.authenticated; return this.authenticated;
} }
/**
* Generally you should not call this method, because on subsequent
* requests the <code>Authentication</code> will be recreated by the
* relevant <code>AuthenticationManager</code>. This method is mostly of
* interest to <code>AuthenticationManager</code>s and unit tests.
*
* @param authorities the new authorities to apply
*/
public void setAuthorities(GrantedAuthority[] authorities) {
this.authorities = authorities;
}
public GrantedAuthority[] getAuthorities() { public GrantedAuthority[] getAuthorities() {
return this.authorities; return this.authorities;
} }

View File

@ -18,10 +18,10 @@ package net.sf.acegisecurity.providers.anonymous;
import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.providers.AbstractAuthenticationToken; import net.sf.acegisecurity.providers.AbstractAuthenticationToken;
import java.io.Serializable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import java.io.Serializable;
/** /**
* Represents an anonymous <code>Authentication</code>. * Represents an anonymous <code>Authentication</code>.
@ -35,6 +35,7 @@ public class AnonymousAuthenticationToken extends AbstractAuthenticationToken
private Object principal; private Object principal;
private GrantedAuthority[] authorities; private GrantedAuthority[] authorities;
private boolean authenticated;
private int keyHash; private int keyHash;
//~ Constructors =========================================================== //~ Constructors ===========================================================
@ -58,14 +59,15 @@ public class AnonymousAuthenticationToken extends AbstractAuthenticationToken
} }
for (int i = 0; i < authorities.length; i++) { for (int i = 0; i < authorities.length; i++) {
Assert.notNull(authorities[i], "Granted authority element " Assert.notNull(authorities[i],
+ i "Granted authority element " + i
+ " is null - GrantedAuthority[] cannot contain any null elements"); + " is null - GrantedAuthority[] cannot contain any null elements");
} }
this.keyHash = key.hashCode(); this.keyHash = key.hashCode();
this.principal = principal; this.principal = principal;
this.authorities = authorities; this.authorities = authorities;
this.authenticated = true;
} }
protected AnonymousAuthenticationToken() { protected AnonymousAuthenticationToken() {
@ -74,22 +76,12 @@ public class AnonymousAuthenticationToken extends AbstractAuthenticationToken
//~ Methods ================================================================ //~ Methods ================================================================
/**
* Ignored (always <code>true</code>).
*
* @param isAuthenticated ignored
*/
public void setAuthenticated(boolean isAuthenticated) { public void setAuthenticated(boolean isAuthenticated) {
// ignored this.authenticated = isAuthenticated;
} }
/**
* Always returns <code>true</code>.
*
* @return true
*/
public boolean isAuthenticated() { public boolean isAuthenticated() {
return true; return this.authenticated;
} }
public GrantedAuthority[] getAuthorities() { public GrantedAuthority[] getAuthorities() {

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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,12 +19,12 @@ import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.UserDetails; import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.providers.AbstractAuthenticationToken; import net.sf.acegisecurity.providers.AbstractAuthenticationToken;
import org.springframework.util.Assert;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import org.springframework.util.Assert;
/** /**
* Represents a successful CAS <code>Authentication</code>. * Represents a successful CAS <code>Authentication</code>.
@ -42,6 +42,7 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken
private String proxyGrantingTicketIou; private String proxyGrantingTicketIou;
private UserDetails userDetails; private UserDetails userDetails;
private GrantedAuthority[] authorities; private GrantedAuthority[] authorities;
private boolean authenticated;
private int keyHash; private int keyHash;
//~ Constructors =========================================================== //~ Constructors ===========================================================
@ -79,9 +80,9 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken
} }
for (int i = 0; i < authorities.length; i++) { for (int i = 0; i < authorities.length; i++) {
Assert.notNull(authorities[i], "Granted authority element " Assert.notNull(authorities[i],
+ i "Granted authority element " + i
+ " is null - GrantedAuthority[] cannot contain any null elements"); + " is null - GrantedAuthority[] cannot contain any null elements");
} }
this.keyHash = key.hashCode(); this.keyHash = key.hashCode();
@ -91,6 +92,7 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken
this.userDetails = userDetails; this.userDetails = userDetails;
this.proxyList = proxyList; this.proxyList = proxyList;
this.proxyGrantingTicketIou = proxyGrantingTicketIou; this.proxyGrantingTicketIou = proxyGrantingTicketIou;
this.authenticated = true;
} }
protected CasAuthenticationToken() { protected CasAuthenticationToken() {
@ -99,22 +101,12 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken
//~ Methods ================================================================ //~ Methods ================================================================
/**
* Ignored (always <code>true</code>).
*
* @param isAuthenticated ignored
*/
public void setAuthenticated(boolean isAuthenticated) { public void setAuthenticated(boolean isAuthenticated) {
// ignored this.authenticated = isAuthenticated;
} }
/**
* Always returns <code>true</code>.
*
* @return true
*/
public boolean isAuthenticated() { public boolean isAuthenticated() {
return true; return this.authenticated;
} }
public GrantedAuthority[] getAuthorities() { public GrantedAuthority[] getAuthorities() {

View File

@ -327,7 +327,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
public Authentication authenticate(Authentication auth) public Authentication authenticate(Authentication auth)
throws AuthenticationException { throws AuthenticationException {
if (auth instanceof UsernamePasswordAuthenticationToken) { if (auth instanceof UsernamePasswordAuthenticationToken) {
UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) auth; UsernamePasswordAuthenticationToken request = (UsernamePasswordAuthenticationToken) auth;
try { try {
//Create the LoginContext object, and pass our InternallCallbackHandler //Create the LoginContext object, and pass our InternallCallbackHandler
@ -340,8 +340,8 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
//create a set to hold the authorities, and add any that have already been applied. //create a set to hold the authorities, and add any that have already been applied.
Set authorities = new HashSet(); Set authorities = new HashSet();
if (token.getAuthorities() != null) { if (request.getAuthorities() != null) {
authorities.addAll(Arrays.asList(token.getAuthorities())); authorities.addAll(Arrays.asList(request.getAuthorities()));
} }
//get the subject principals and pass them to each of the AuthorityGranters //get the subject principals and pass them to each of the AuthorityGranters
@ -368,19 +368,21 @@ public class JaasAuthenticationProvider implements AuthenticationProvider,
} }
//Convert the authorities set back to an array and apply it to the token. //Convert the authorities set back to an array and apply it to the token.
token.setAuthorities((GrantedAuthority[]) authorities.toArray( UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(request
new GrantedAuthority[authorities.size()])); .getPrincipal(), request.getCredentials(),
(GrantedAuthority[]) authorities.toArray(
new GrantedAuthority[authorities.size()]));
//Publish the success event //Publish the success event
publishSuccessEvent(token); publishSuccessEvent(result);
//we're done, return the token. //we're done, return the token.
return token; return result;
} catch (LoginException loginException) { } catch (LoginException loginException) {
AcegiSecurityException ase = loginExceptionResolver AcegiSecurityException ase = loginExceptionResolver
.resolveException(loginException); .resolveException(loginException);
publishFailureEvent(token, ase); publishFailureEvent(request, ase);
throw ase; throw ase;
} }
} }

View File

@ -42,6 +42,7 @@ public class RememberMeAuthenticationToken extends AbstractAuthenticationToken
private Object principal; private Object principal;
private GrantedAuthority[] authorities; private GrantedAuthority[] authorities;
private int keyHash; private int keyHash;
private boolean authenticated;
//~ Constructors =========================================================== //~ Constructors ===========================================================
@ -72,6 +73,7 @@ public class RememberMeAuthenticationToken extends AbstractAuthenticationToken
this.keyHash = key.hashCode(); this.keyHash = key.hashCode();
this.principal = principal; this.principal = principal;
this.authorities = authorities; this.authorities = authorities;
this.authenticated = true;
} }
protected RememberMeAuthenticationToken() { protected RememberMeAuthenticationToken() {
@ -80,22 +82,12 @@ public class RememberMeAuthenticationToken extends AbstractAuthenticationToken
//~ Methods ================================================================ //~ Methods ================================================================
/**
* Ignored (always <code>true</code>).
*
* @param isAuthenticated ignored
*/
public void setAuthenticated(boolean isAuthenticated) { public void setAuthenticated(boolean isAuthenticated) {
// ignored this.authenticated = isAuthenticated;
} }
/**
* Always returns <code>true</code>.
*
* @return true
*/
public boolean isAuthenticated() { public boolean isAuthenticated() {
return true; return this.authenticated;
} }
public GrantedAuthority[] getAuthorities() { public GrantedAuthority[] getAuthorities() {

View File

@ -34,6 +34,7 @@ public class RunAsUserToken extends AbstractAuthenticationToken {
private Object principal; private Object principal;
private GrantedAuthority[] authorities; private GrantedAuthority[] authorities;
private int keyHash; private int keyHash;
private boolean authenticated;
//~ Constructors =========================================================== //~ Constructors ===========================================================
@ -45,6 +46,7 @@ public class RunAsUserToken extends AbstractAuthenticationToken {
this.principal = principal; this.principal = principal;
this.credentials = credentials; this.credentials = credentials;
this.originalAuthentication = originalAuthentication; this.originalAuthentication = originalAuthentication;
this.authenticated = true;
} }
protected RunAsUserToken() { protected RunAsUserToken() {
@ -53,22 +55,12 @@ public class RunAsUserToken extends AbstractAuthenticationToken {
//~ Methods ================================================================ //~ Methods ================================================================
/** public void setAuthenticated(boolean isAuthenticated) {
* Setting is ignored. Always considered authenticated. this.authenticated = isAuthenticated;
*
* @param ignored DOCUMENT ME!
*/
public void setAuthenticated(boolean ignored) {
// ignored
} }
/**
* Always returns <code>true</code>.
*
* @return DOCUMENT ME!
*/
public boolean isAuthenticated() { public boolean isAuthenticated() {
return true; return this.authenticated;
} }
public GrantedAuthority[] getAuthorities() { public GrantedAuthority[] getAuthorities() {

View File

@ -83,14 +83,14 @@ public class MethodSecurityInterceptorTests extends TestCase {
SecurityContextHolder.getContext().setAuthentication(null); SecurityContextHolder.getContext().setAuthentication(null);
} }
public void testCallingAPublicMethodWhenPresentingAnAuthenticationObjectWillProperlySetItsIsAuthenticatedProperty() public void testCallingAPublicMethodWhenPresentingAnAuthenticationObjectWillNotChangeItsIsAuthenticatedProperty()
throws Exception { throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test",
"Password", "Password");
new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_THIS_IS_NOT_REQUIRED_AS_IT_IS_PUBLIC")});
assertTrue(!token.isAuthenticated()); assertTrue(!token.isAuthenticated());
SecurityContextHolder.getContext().setAuthentication(token); SecurityContextHolder.getContext().setAuthentication(token);
// The associated MockAuthenticationManager WILL accept the above UsernamePasswordAuthenticationToken
ITargetObject target = makeInterceptedTarget(); ITargetObject target = makeInterceptedTarget();
String result = target.publicMakeLowerCase("HELLO"); String result = target.publicMakeLowerCase("HELLO");
assertEquals("hello net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken false", assertEquals("hello net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken false",
@ -158,13 +158,13 @@ public class MethodSecurityInterceptorTests extends TestCase {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test",
"Password", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_LOWER")}); new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_LOWER")});
assertTrue(!token.isAuthenticated()); assertTrue(token.isAuthenticated());
SecurityContextHolder.getContext().setAuthentication(token); SecurityContextHolder.getContext().setAuthentication(token);
ITargetObject target = makeInterceptedTargetWithoutAnAfterInvocationManager(); ITargetObject target = makeInterceptedTargetWithoutAnAfterInvocationManager();
String result = target.makeLowerCase("HELLO"); String result = target.makeLowerCase("HELLO");
// Note we check the isAuthenticated becomes true in following line // Note we check the isAuthenticated remained true in following line
assertEquals("hello net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken true", assertEquals("hello net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken true",
result); result);
@ -203,11 +203,11 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testRejectsCallsWhenAuthenticationIsIncorrect() public void testRejectsCallsWhenAuthenticationIsIncorrect()
throws Exception { throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test",
"Password", "Password");
new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_LOWER")});
assertTrue(!token.isAuthenticated()); assertTrue(!token.isAuthenticated());
SecurityContextHolder.getContext().setAuthentication(token); SecurityContextHolder.getContext().setAuthentication(token);
// NB: The associated MockAuthenticationManager WILL reject the above UsernamePasswordAuthenticationToken
ITargetObject target = makeInterceptedTargetRejectsAuthentication(); ITargetObject target = makeInterceptedTargetRejectsAuthentication();
try { try {

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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -51,9 +51,30 @@ public class UsernamePasswordAuthenticationTokenTests extends TestCase {
public void testAuthenticated() { public void testAuthenticated() {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test",
"Password", null); "Password", null);
assertTrue(!token.isAuthenticated());
token.setAuthenticated(true); // check default given we passed some GrantedAuthorty[]s (well, we passed null)
assertTrue(token.isAuthenticated()); assertTrue(token.isAuthenticated());
// check explicit set to untrusted (we can safely go from trusted to untrusted, but not the reverse)
token.setAuthenticated(false);
assertTrue(!token.isAuthenticated());
// Now let's create a UsernamePasswordAuthenticationToken without any GrantedAuthorty[]s (different constructor)
token = new UsernamePasswordAuthenticationToken("Test", "Password");
assertTrue(!token.isAuthenticated());
// check we're allowed to still set it to untrusted
token.setAuthenticated(false);
assertTrue(!token.isAuthenticated());
// check denied changing it to trusted
try {
token.setAuthenticated(true);
fail("Should have prohibited setAuthenticated(true)");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
} }
public void testGetters() { public void testGetters() {
@ -67,19 +88,6 @@ public class UsernamePasswordAuthenticationTokenTests extends TestCase {
assertEquals("ROLE_TWO", token.getAuthorities()[1].getAuthority()); assertEquals("ROLE_TWO", token.getAuthorities()[1].getAuthority());
} }
public void testNewAuthorities() {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test",
"Password", null);
assertEquals("Test", token.getPrincipal());
assertEquals("Password", token.getCredentials());
assertEquals(null, token.getAuthorities());
token.setAuthorities(new GrantedAuthority[] {new GrantedAuthorityImpl(
"ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
assertEquals("ROLE_ONE", token.getAuthorities()[0].getAuthority());
assertEquals("ROLE_TWO", token.getAuthorities()[1].getAuthority());
}
public void testNoArgConstructor() { public void testNoArgConstructor() {
try { try {
new UsernamePasswordAuthenticationToken(); new UsernamePasswordAuthenticationToken();

View File

@ -159,7 +159,6 @@ public class AnonymousAuthenticationTokenTests extends TestCase {
"Password", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")}); "ROLE_TWO")});
token2.setAuthenticated(true);
assertFalse(token1.equals(token2)); assertFalse(token1.equals(token2));
} }
@ -184,7 +183,7 @@ public class AnonymousAuthenticationTokenTests extends TestCase {
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")}); "ROLE_TWO")});
assertTrue(token.isAuthenticated()); assertTrue(token.isAuthenticated());
token.setAuthenticated(false); // ignored token.setAuthenticated(false);
assertTrue(token.isAuthenticated()); assertTrue(!token.isAuthenticated());
} }
} }

View File

@ -223,7 +223,6 @@ public class CasAuthenticationTokenTests extends TestCase {
"Password", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")}); "ROLE_TWO")});
token2.setAuthenticated(true);
assertTrue(!token1.equals(token2)); assertTrue(!token1.equals(token2));
} }
@ -295,15 +294,15 @@ public class CasAuthenticationTokenTests extends TestCase {
assertTrue(!token1.equals(token2)); assertTrue(!token1.equals(token2));
} }
public void testSetAuthenticatedIgnored() { public void testSetAuthenticated() {
CasAuthenticationToken token = new CasAuthenticationToken("key", CasAuthenticationToken token = new CasAuthenticationToken("key",
"Test", "Password", "Test", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")}, makeUserDetails(), new Vector(), "ROLE_TWO")}, makeUserDetails(), new Vector(),
"PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt"); "PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt");
assertTrue(token.isAuthenticated()); assertTrue(token.isAuthenticated());
token.setAuthenticated(false); // ignored token.setAuthenticated(false);
assertTrue(token.isAuthenticated()); assertTrue(!token.isAuthenticated());
} }
public void testToString() { public void testToString() {

View File

@ -159,7 +159,6 @@ public class RememberMeAuthenticationTokenTests extends TestCase {
"Password", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")}); "ROLE_TWO")});
token2.setAuthenticated(true);
assertFalse(token1.equals(token2)); assertFalse(token1.equals(token2));
} }
@ -184,7 +183,7 @@ public class RememberMeAuthenticationTokenTests extends TestCase {
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")}); "ROLE_TWO")});
assertTrue(token.isAuthenticated()); assertTrue(token.isAuthenticated());
token.setAuthenticated(false); // ignored token.setAuthenticated(false);
assertTrue(token.isAuthenticated()); assertTrue(!token.isAuthenticated());
} }
} }

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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -49,14 +49,14 @@ public class RunAsUserTokenTests extends TestCase {
junit.textui.TestRunner.run(RunAsUserTokenTests.class); junit.textui.TestRunner.run(RunAsUserTokenTests.class);
} }
public void testAuthenticationSettingAlwaysReturnsTrue() { public void testAuthenticationSetting() {
RunAsUserToken token = new RunAsUserToken("my_password", "Test", RunAsUserToken token = new RunAsUserToken("my_password", "Test",
"Password", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
"ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class);
assertTrue(token.isAuthenticated()); assertTrue(token.isAuthenticated());
token.setAuthenticated(false); token.setAuthenticated(false);
assertTrue(token.isAuthenticated()); assertTrue(!token.isAuthenticated());
} }
public void testGetters() { public void testGetters() {

View File

@ -26,17 +26,18 @@
</properties> </properties>
<body> <body>
<release version="0.9.0" date="In CVS"> <release version="0.9.0" date="In CVS">
<action dev="benalex" type="update">JdbcDaoImpl modified to support synthetic primary keys</action> <action dev="benalex" type="update">JdbcDaoImpl modified to support synthetic primary keys</action>
<action dev="benalex" type="update">Greatly improve BasicAclEntryAfterInvocationCollectionFilteringProvider performance with large collections (if the principal has access to relatively few collection elements)</action> <action dev="benalex" type="update">Greatly improve BasicAclEntryAfterInvocationCollectionFilteringProvider performance with large collections (if the principal has access to relatively few collection elements)</action>
<action dev="benalex" type="update">Reorder DaoAuthenticationProvider exception logic as per developer list discussion</action> <action dev="benalex" type="update">Reorder DaoAuthenticationProvider exception logic as per developer list discussion</action>
<action dev="benalex" type="update">ContextHolder refactored and replaced by SecurityContextHolder</action> <action dev="benalex" type="update">ContextHolder refactored and replaced by SecurityContextHolder</action>
<action dev="benalex" type="fix">Made AclEntry Serializable (correct issue with BasicAclEntryCache)</action> <action dev="benalex" type="fix">Made AclEntry Serializable (correct issue with BasicAclEntryCache)</action>
<action dev="luke_t" type="update">Changed order of credentials verification and expiry checking in DaoAuthenticationProvider. Password must now be successfully verified before expired credentials are reported. </action> <action dev="luke_t" type="update">Changed order of credentials verification and expiry checking in DaoAuthenticationProvider. Password must now be successfully verified before expired credentials are reported. </action>
<action dev="benalex" type="update">AnonymousProcessingFilter offers protected method to control when it should execute</action> <action dev="benalex" type="update">AnonymousProcessingFilter offers protected method to control when it should execute</action>
<action dev="benalex" type="fix">AbstractAuthenticationToken.getName() now returns username alone if UserDetails present</action> <action dev="benalex" type="fix">AbstractAuthenticationToken.getName() now returns username alone if UserDetails present</action>
<action dev="raykrueger" type="update">AuthorityGranter.grant now returns a java.util.Set of role names, instead of a single role name</action> <action dev="raykrueger" type="update">AuthorityGranter.grant now returns a java.util.Set of role names, instead of a single role name</action>
<action dev="benalex" type="update">JavaDoc improvements</action> <action dev="benalex" type="update">JavaDoc improvements</action>
<action dev="benalex" type="fix">Correct synchronization issue with FilterToBeanProxy initialization</action> <action dev="benalex" type="fix">Correct synchronization issue with FilterToBeanProxy initialization (as per developer list discussion)</action>
<action dev="benalex" type="update">Refactor Authentication.isAuthenticated() handling to be more performance (as per developer list discussion)</action>
</release> </release>
<release version="0.8.2" date="2005-04-20"> <release version="0.8.2" date="2005-04-20">
<action dev="benalex" type="fix">Correct location of AuthenticationSimpleHttpInvokerRequestExecutor in clientContext.xml</action> <action dev="benalex" type="fix">Correct location of AuthenticationSimpleHttpInvokerRequestExecutor in clientContext.xml</action>