SEC-1399: Removed AbstractAuthenticationManager.

MockAuthenticationManager was the only other subclass (apart from the main ProviderManager) and has been removed also.
This commit is contained in:
Luke Taylor 2010-02-20 21:35:39 +00:00
parent dacb8dd25a
commit ea7ccc718d
6 changed files with 60 additions and 165 deletions

View File

@ -1,84 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.springframework.security.authentication;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
/**
* An abstract implementation of the {@link AuthenticationManager}.
*
* @author Wesley Hall
*/
public abstract class AbstractAuthenticationManager implements AuthenticationManager {
//~ Instance fields ================================================================================================
private boolean clearExtraInformation = false;
//~ Methods ========================================================================================================
/**
* An implementation of the <code>authenticate</code> method that calls the abstract method
* <code>doAuthenticatation</code> to do its work.
* <p>
* If doAuthenticate throws an <code>AuthenticationException</code> then the exception is populated
* with the failed <code>Authentication</code> object that failed.
*
* @param authRequest the authentication request object
*
* @return a fully authenticated object including credentials
*
* @throws AuthenticationException if authentication fails
*/
public final Authentication authenticate(Authentication authRequest) throws AuthenticationException {
try {
return doAuthentication(authRequest);
} catch (AuthenticationException e) {
e.setAuthentication(authRequest);
if (clearExtraInformation) {
e.clearExtraInformation();
}
throw e;
}
}
/**
* Concrete implementations of this class override this method to provide the authentication service.
* <p>
* The contract for this method is documented in the
* {@link AuthenticationManager#authenticate(Authentication)}.
*
* @param authentication the authentication request object
*
* @return a fully authenticated object including credentials
*
* @throws AuthenticationException if authentication fails
*/
protected abstract Authentication doAuthentication(Authentication authentication) throws AuthenticationException;
/**
* If set to true, the <tt>extraInformation</tt> set on an <tt>AuthenticationException</tt> will be cleared
* before rethrowing it. This is useful for use with remoting protocols where the information shouldn't
* be serialized to the client. Defaults to 'false'.
*
* @see org.springframework.security.core.AuthenticationException#getExtraInformation()
*/
public void setClearExtraInformation(boolean clearExtraInformation) {
this.clearExtraInformation = clearExtraInformation;
}
}

View File

@ -65,7 +65,7 @@ import org.springframework.util.Assert;
* *
* @see DefaultAuthenticationEventPublisher * @see DefaultAuthenticationEventPublisher
*/ */
public class ProviderManager extends AbstractAuthenticationManager implements MessageSourceAware, InitializingBean { public class ProviderManager implements AuthenticationManager, MessageSourceAware, InitializingBean {
//~ Static fields/initializers ===================================================================================== //~ Static fields/initializers =====================================================================================
private static final Log logger = LogFactory.getLog(ProviderManager.class); private static final Log logger = LogFactory.getLog(ProviderManager.class);
@ -77,6 +77,8 @@ public class ProviderManager extends AbstractAuthenticationManager implements Me
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor(); protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
private AuthenticationManager parent; private AuthenticationManager parent;
private boolean clearExtraInformation = false;
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
@ -104,17 +106,20 @@ public class ProviderManager extends AbstractAuthenticationManager implements Me
* *
* @throws AuthenticationException if authentication fails. * @throws AuthenticationException if authentication fails.
*/ */
public Authentication doAuthentication(Authentication authentication) throws AuthenticationException { public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Class<? extends Authentication> toTest = authentication.getClass(); Class<? extends Authentication> toTest = authentication.getClass();
AuthenticationException lastException = null; AuthenticationException lastException = null;
Authentication result = null; Authentication result = null;
boolean debug = logger.isDebugEnabled();
for (AuthenticationProvider provider : getProviders()) { for (AuthenticationProvider provider : getProviders()) {
if (!provider.supports(toTest)) { if (!provider.supports(toTest)) {
continue; continue;
} }
if (debug) {
logger.debug("Authentication attempt using " + provider.getClass().getName()); logger.debug("Authentication attempt using " + provider.getClass().getName());
}
try { try {
result = provider.authenticate(authentication); result = provider.authenticate(authentication);
@ -124,8 +129,8 @@ public class ProviderManager extends AbstractAuthenticationManager implements Me
break; break;
} }
} catch (AccountStatusException e) { } catch (AccountStatusException e) {
prepareException(e, authentication);
// SEC-546: Avoid polling additional providers if auth failure is due to invalid account status // SEC-546: Avoid polling additional providers if auth failure is due to invalid account status
eventPublisher.publishAuthenticationFailure(e, authentication);
throw e; throw e;
} catch (AuthenticationException e) { } catch (AuthenticationException e) {
lastException = e; lastException = e;
@ -157,10 +162,19 @@ public class ProviderManager extends AbstractAuthenticationManager implements Me
} }
eventPublisher.publishAuthenticationFailure(lastException, authentication); eventPublisher.publishAuthenticationFailure(lastException, authentication);
prepareException(lastException, authentication);
throw lastException; throw lastException;
} }
private void prepareException(AuthenticationException ex, Authentication auth) {
ex.setAuthentication(auth);
if (clearExtraInformation) {
ex.clearExtraInformation();
}
}
/** /**
* Copies the authentication details from a source Authentication object to a destination one, provided the * Copies the authentication details from a source Authentication object to a destination one, provided the
* latter does not already have one set. * latter does not already have one set.
@ -211,6 +225,17 @@ public class ProviderManager extends AbstractAuthenticationManager implements Me
this.providers = providers; this.providers = providers;
} }
/**
* If set to true, the <tt>extraInformation</tt> set on an <tt>AuthenticationException</tt> will be cleared
* before rethrowing it. This is useful for use with remoting protocols where the information shouldn't
* be serialized to the client. Defaults to 'false'.
*
* @see org.springframework.security.core.AuthenticationException#getExtraInformation()
*/
public void setClearExtraInformation(boolean clearExtraInformation) {
this.clearExtraInformation = clearExtraInformation;
}
private static final class NullEventPublisher implements AuthenticationEventPublisher { private static final class NullEventPublisher implements AuthenticationEventPublisher {
public void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication) {} public void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication) {}
public void publishAuthenticationSuccess(Authentication authentication) {} public void publishAuthenticationSuccess(Authentication authentication) {}

View File

@ -57,7 +57,7 @@ public class RemoteAuthenticationManagerImpl implements RemoteAuthenticationMana
} }
} }
public AuthenticationManager getAuthenticationManager() { protected AuthenticationManager getAuthenticationManager() {
return authenticationManager; return authenticationManager;
} }

View File

@ -1,52 +0,0 @@
/* Copyright 2004, 2005, 2006 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 org.springframework.security;
import org.springframework.security.authentication.AbstractAuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
/**
* Simply accepts as valid whatever is passed to it, if <code>grantAccess</code> is set to <code>true</code>.
*
* @author Ben Alex
* @author Wesley Hall
*/
public class MockAuthenticationManager extends AbstractAuthenticationManager {
//~ Instance fields ================================================================================================
private boolean grantAccess = true;
//~ Constructors ===================================================================================================
public MockAuthenticationManager(boolean grantAccess) {
this.grantAccess = grantAccess;
}
public MockAuthenticationManager() {
}
//~ Methods ========================================================================================================
public Authentication doAuthentication(Authentication authentication) throws AuthenticationException {
if (grantAccess) {
return authentication;
} else {
throw new BadCredentialsException("MockAuthenticationManager instructed to deny access");
}
}
}

View File

@ -15,11 +15,15 @@
package org.springframework.security.authentication.rcp; package org.springframework.security.authentication.rcp;
import junit.framework.TestCase; import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
import org.springframework.security.MockAuthenticationManager; import org.junit.Test;
import org.springframework.security.authentication.rcp.RemoteAuthenticationException; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.rcp.RemoteAuthenticationManagerImpl; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
/** /**
@ -27,27 +31,20 @@ import org.springframework.security.authentication.rcp.RemoteAuthenticationManag
* *
* @author Ben Alex * @author Ben Alex
*/ */
public class RemoteAuthenticationManagerImplTests extends TestCase { public class RemoteAuthenticationManagerImplTests {
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
@Test(expected=RemoteAuthenticationException.class)
public void testFailedAuthenticationReturnsRemoteAuthenticationException() { public void testFailedAuthenticationReturnsRemoteAuthenticationException() {
RemoteAuthenticationManagerImpl manager = new RemoteAuthenticationManagerImpl(); RemoteAuthenticationManagerImpl manager = new RemoteAuthenticationManagerImpl();
manager.setAuthenticationManager(new MockAuthenticationManager(false)); AuthenticationManager am = mock(AuthenticationManager.class);
when(am.authenticate(any(Authentication.class))).thenThrow(new BadCredentialsException(""));
manager.setAuthenticationManager(am);
try {
manager.attemptAuthentication("rod", "password"); manager.attemptAuthentication("rod", "password");
fail("Should have thrown RemoteAuthenticationException");
} catch (RemoteAuthenticationException expected) {
assertTrue(true);
}
}
public void testGettersSetters() {
RemoteAuthenticationManagerImpl manager = new RemoteAuthenticationManagerImpl();
manager.setAuthenticationManager(new MockAuthenticationManager(true));
assertNotNull(manager.getAuthenticationManager());
} }
@Test
public void testStartupChecksAuthenticationManagerSet() throws Exception { public void testStartupChecksAuthenticationManagerSet() throws Exception {
RemoteAuthenticationManagerImpl manager = new RemoteAuthenticationManagerImpl(); RemoteAuthenticationManagerImpl manager = new RemoteAuthenticationManagerImpl();
@ -55,17 +52,19 @@ public class RemoteAuthenticationManagerImplTests extends TestCase {
manager.afterPropertiesSet(); manager.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException"); fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
assertTrue(true);
} }
manager.setAuthenticationManager(new MockAuthenticationManager(true)); manager.setAuthenticationManager(mock(AuthenticationManager.class));
manager.afterPropertiesSet(); manager.afterPropertiesSet();
assertTrue(true); assertTrue(true);
} }
@Test
public void testSuccessfulAuthentication() { public void testSuccessfulAuthentication() {
RemoteAuthenticationManagerImpl manager = new RemoteAuthenticationManagerImpl(); RemoteAuthenticationManagerImpl manager = new RemoteAuthenticationManagerImpl();
manager.setAuthenticationManager(new MockAuthenticationManager(true)); AuthenticationManager am = mock(AuthenticationManager.class);
when(am.authenticate(any(Authentication.class))).thenReturn(new TestingAuthenticationToken("u","p","A"));
manager.setAuthenticationManager(am);
manager.attemptAuthentication("rod", "password"); manager.attemptAuthentication("rod", "password");
} }

View File

@ -1,6 +1,7 @@
package org.springframework.security.provisioning; package org.springframework.security.provisioning;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -13,10 +14,10 @@ import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.MockAuthenticationManager;
import org.springframework.security.PopulatedDatabase; import org.springframework.security.PopulatedDatabase;
import org.springframework.security.TestDataSource; import org.springframework.security.TestDataSource;
import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -155,7 +156,10 @@ public class JdbcUserDetailsManagerTests {
public void changePasswordSucceedsWithIfReAuthenticationSucceeds() { public void changePasswordSucceedsWithIfReAuthenticationSucceeds() {
insertJoe(); insertJoe();
Authentication currentAuth = authenticateJoe(); Authentication currentAuth = authenticateJoe();
manager.setAuthenticationManager(new MockAuthenticationManager(true)); AuthenticationManager am = mock(AuthenticationManager.class);
when(am.authenticate(currentAuth)).thenReturn(currentAuth);
manager.setAuthenticationManager(am);
manager.changePassword("password", "newPassword"); manager.changePassword("password", "newPassword");
UserDetails newJoe = manager.loadUserByUsername("joe"); UserDetails newJoe = manager.loadUserByUsername("joe");
@ -172,7 +176,10 @@ public class JdbcUserDetailsManagerTests {
public void changePasswordFailsIfReAuthenticationFails() { public void changePasswordFailsIfReAuthenticationFails() {
insertJoe(); insertJoe();
authenticateJoe(); authenticateJoe();
manager.setAuthenticationManager(new MockAuthenticationManager(false)); AuthenticationManager am = mock(AuthenticationManager.class);
when(am.authenticate(any(Authentication.class))).thenThrow(new BadCredentialsException(""));
manager.setAuthenticationManager(am);
try { try {
manager.changePassword("password", "newPassword"); manager.changePassword("password", "newPassword");