diff --git a/core/src/main/java/org/springframework/security/authentication/AbstractAuthenticationManager.java b/core/src/main/java/org/springframework/security/authentication/AbstractAuthenticationManager.java
deleted file mode 100644
index 5574ebb7c4..0000000000
--- a/core/src/main/java/org/springframework/security/authentication/AbstractAuthenticationManager.java
+++ /dev/null
@@ -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 authenticate
method that calls the abstract method
- * doAuthenticatation
to do its work.
- *
- * If doAuthenticate throws an AuthenticationException
then the exception is populated
- * with the failed Authentication
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.
- *
- * 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 extraInformation set on an AuthenticationException 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;
- }
-}
diff --git a/core/src/main/java/org/springframework/security/authentication/ProviderManager.java b/core/src/main/java/org/springframework/security/authentication/ProviderManager.java
index 9117bb1109..55badc8879 100644
--- a/core/src/main/java/org/springframework/security/authentication/ProviderManager.java
+++ b/core/src/main/java/org/springframework/security/authentication/ProviderManager.java
@@ -65,7 +65,7 @@ import org.springframework.util.Assert;
*
* @see DefaultAuthenticationEventPublisher
*/
-public class ProviderManager extends AbstractAuthenticationManager implements MessageSourceAware, InitializingBean {
+public class ProviderManager implements AuthenticationManager, MessageSourceAware, InitializingBean {
//~ Static fields/initializers =====================================================================================
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();
private AuthenticationManager parent;
+ private boolean clearExtraInformation = false;
+
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
@@ -104,17 +106,20 @@ public class ProviderManager extends AbstractAuthenticationManager implements Me
*
* @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();
AuthenticationException lastException = null;
Authentication result = null;
+ boolean debug = logger.isDebugEnabled();
for (AuthenticationProvider provider : getProviders()) {
if (!provider.supports(toTest)) {
continue;
}
- logger.debug("Authentication attempt using " + provider.getClass().getName());
+ if (debug) {
+ logger.debug("Authentication attempt using " + provider.getClass().getName());
+ }
try {
result = provider.authenticate(authentication);
@@ -124,8 +129,8 @@ public class ProviderManager extends AbstractAuthenticationManager implements Me
break;
}
} catch (AccountStatusException e) {
+ prepareException(e, authentication);
// SEC-546: Avoid polling additional providers if auth failure is due to invalid account status
- eventPublisher.publishAuthenticationFailure(e, authentication);
throw e;
} catch (AuthenticationException e) {
lastException = e;
@@ -157,10 +162,19 @@ public class ProviderManager extends AbstractAuthenticationManager implements Me
}
eventPublisher.publishAuthenticationFailure(lastException, authentication);
+ prepareException(lastException, authentication);
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
* latter does not already have one set.
@@ -211,6 +225,17 @@ public class ProviderManager extends AbstractAuthenticationManager implements Me
this.providers = providers;
}
+ /**
+ * If set to true, the extraInformation set on an AuthenticationException 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 {
public void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication) {}
public void publishAuthenticationSuccess(Authentication authentication) {}
diff --git a/core/src/main/java/org/springframework/security/authentication/rcp/RemoteAuthenticationManagerImpl.java b/core/src/main/java/org/springframework/security/authentication/rcp/RemoteAuthenticationManagerImpl.java
index 528f1a81ce..90b00bc89c 100644
--- a/core/src/main/java/org/springframework/security/authentication/rcp/RemoteAuthenticationManagerImpl.java
+++ b/core/src/main/java/org/springframework/security/authentication/rcp/RemoteAuthenticationManagerImpl.java
@@ -57,7 +57,7 @@ public class RemoteAuthenticationManagerImpl implements RemoteAuthenticationMana
}
}
- public AuthenticationManager getAuthenticationManager() {
+ protected AuthenticationManager getAuthenticationManager() {
return authenticationManager;
}
diff --git a/core/src/test/java/org/springframework/security/MockAuthenticationManager.java b/core/src/test/java/org/springframework/security/MockAuthenticationManager.java
deleted file mode 100644
index 0d5dcf3600..0000000000
--- a/core/src/test/java/org/springframework/security/MockAuthenticationManager.java
+++ /dev/null
@@ -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 grantAccess
is set to true
.
- *
- * @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");
- }
- }
-}
diff --git a/core/src/test/java/org/springframework/security/authentication/rcp/RemoteAuthenticationManagerImplTests.java b/core/src/test/java/org/springframework/security/authentication/rcp/RemoteAuthenticationManagerImplTests.java
index 4a6ddd478c..5da7784d2e 100644
--- a/core/src/test/java/org/springframework/security/authentication/rcp/RemoteAuthenticationManagerImplTests.java
+++ b/core/src/test/java/org/springframework/security/authentication/rcp/RemoteAuthenticationManagerImplTests.java
@@ -15,11 +15,15 @@
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.springframework.security.authentication.rcp.RemoteAuthenticationException;
-import org.springframework.security.authentication.rcp.RemoteAuthenticationManagerImpl;
+import org.junit.Test;
+import org.springframework.security.authentication.AuthenticationManager;
+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
*/
-public class RemoteAuthenticationManagerImplTests extends TestCase {
+public class RemoteAuthenticationManagerImplTests {
//~ Methods ========================================================================================================
+ @Test(expected=RemoteAuthenticationException.class)
public void testFailedAuthenticationReturnsRemoteAuthenticationException() {
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");
- 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());
+ manager.attemptAuthentication("rod", "password");
}
+ @Test
public void testStartupChecksAuthenticationManagerSet() throws Exception {
RemoteAuthenticationManagerImpl manager = new RemoteAuthenticationManagerImpl();
@@ -55,17 +52,19 @@ public class RemoteAuthenticationManagerImplTests extends TestCase {
manager.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
- assertTrue(true);
}
- manager.setAuthenticationManager(new MockAuthenticationManager(true));
+ manager.setAuthenticationManager(mock(AuthenticationManager.class));
manager.afterPropertiesSet();
assertTrue(true);
}
+ @Test
public void testSuccessfulAuthentication() {
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");
}
diff --git a/core/src/test/java/org/springframework/security/provisioning/JdbcUserDetailsManagerTests.java b/core/src/test/java/org/springframework/security/provisioning/JdbcUserDetailsManagerTests.java
index 776aae3853..58e980e486 100644
--- a/core/src/test/java/org/springframework/security/provisioning/JdbcUserDetailsManagerTests.java
+++ b/core/src/test/java/org/springframework/security/provisioning/JdbcUserDetailsManagerTests.java
@@ -1,6 +1,7 @@
package org.springframework.security.provisioning;
import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
import java.util.Collections;
import java.util.HashMap;
@@ -13,10 +14,10 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.security.MockAuthenticationManager;
import org.springframework.security.PopulatedDatabase;
import org.springframework.security.TestDataSource;
import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
@@ -155,7 +156,10 @@ public class JdbcUserDetailsManagerTests {
public void changePasswordSucceedsWithIfReAuthenticationSucceeds() {
insertJoe();
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");
UserDetails newJoe = manager.loadUserByUsername("joe");
@@ -172,7 +176,10 @@ public class JdbcUserDetailsManagerTests {
public void changePasswordFailsIfReAuthenticationFails() {
insertJoe();
authenticateJoe();
- manager.setAuthenticationManager(new MockAuthenticationManager(false));
+ AuthenticationManager am = mock(AuthenticationManager.class);
+ when(am.authenticate(any(Authentication.class))).thenThrow(new BadCredentialsException(""));
+
+ manager.setAuthenticationManager(am);
try {
manager.changePassword("password", "newPassword");