diff --git a/core/src/main/java/org/springframework/security/providers/DaoAuthoritiesPopulator.java b/core/src/main/java/org/springframework/security/providers/DaoAuthoritiesPopulator.java deleted file mode 100644 index a08378420a..0000000000 --- a/core/src/main/java/org/springframework/security/providers/DaoAuthoritiesPopulator.java +++ /dev/null @@ -1,54 +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.providers; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.security.AuthenticationException; -import org.springframework.security.userdetails.UserDetails; -import org.springframework.security.userdetails.UserDetailsService; -import org.springframework.util.Assert; - -/** - * Populates the CAS authorities via an {@link org.springframework.security.userdetails.UserDetailsService}.
The additional information (username,
- * password, enabled status etc) an AuthenticationDao implementation provides about a User
- * is ignored. Only the GrantedAuthoritys are relevant to this class.
May throw any
* AuthenticationException or return null if the authorities are unavailable.
null)
* @param credentials the service/proxy ticket ID from CAS (cannot be
* null)
- * @param authorities the authorities granted to the user (from {@link
- * CasAuthoritiesPopulator}) (cannot be null)
- * @param userDetails the user details (from {@link
- * CasAuthoritiesPopulator}) (cannot be null)
+ * @param authorities the authorities granted to the user (from the {@link
+ * org.springframework.security.userdetails.UserDetailsService}) (cannot be null)
+ * @param userDetails the user details (from the {@link
+ * org.springframework.security.userdetails.UserDetailsService}) (cannot be null)
* @param proxyList the list of proxies from CAS (cannot be
* null)
* @param proxyGrantingTicketIou the PGT-IOU ID from CAS (cannot be
diff --git a/core/src/main/java/org/springframework/security/providers/cas/CasAuthoritiesPopulator.java b/core/src/main/java/org/springframework/security/providers/cas/CasAuthoritiesPopulator.java
deleted file mode 100644
index 8bc1c23fae..0000000000
--- a/core/src/main/java/org/springframework/security/providers/cas/CasAuthoritiesPopulator.java
+++ /dev/null
@@ -1,50 +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.providers.cas;
-
-import org.springframework.security.providers.AuthoritiesPopulator;
-
-
-/**
- * - * Backwards compatible extension to the {@link AuthoritiesPopulator} interface. - * This interface has usefulness outside of the CAS usecase. Thus, the {@link AuthoritiesPopulator} - * interface was refactored in. - *
- *
- * Populates the UserDetails associated with a CAS authenticated
- * user.
- *
- * CAS does not provide the authorities (roles) granted to a user. It merely
- * authenticates their identity. As Spring Security needs
- * to know the authorities granted to a user in order to construct a valid
- * Authentication object, implementations of this interface will
- * provide this information.
- *
- * Implementations should not perform any caching. They will only be called - * when a refresh is required. - *
- * - * @author Ben Alex - * @version $Id$ - */ -public interface CasAuthoritiesPopulator extends AuthoritiesPopulator { - -} diff --git a/core/src/main/java/org/springframework/security/providers/cas/populator/DaoCasAuthoritiesPopulator.java b/core/src/main/java/org/springframework/security/providers/cas/populator/DaoCasAuthoritiesPopulator.java deleted file mode 100644 index 19d46b2af6..0000000000 --- a/core/src/main/java/org/springframework/security/providers/cas/populator/DaoCasAuthoritiesPopulator.java +++ /dev/null @@ -1,35 +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.providers.cas.populator; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.security.providers.DaoAuthoritiesPopulator; - - -/** - * Backwards compatible placeholder. - * This class will be removed, use {@link DaoAuthoritiesPopulator} instead. - * - * @deprecated Use {@link org.springframework.security.providers.DaoAuthoritiesPopulator} - * @author Ben Alex - * @version $Id$ - */ -public class DaoCasAuthoritiesPopulator extends DaoAuthoritiesPopulator implements InitializingBean { - - public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); - } -} diff --git a/core/src/main/java/org/springframework/security/providers/cas/populator/package.html b/core/src/main/java/org/springframework/security/providers/cas/populator/package.html deleted file mode 100644 index 7e49e0f543..0000000000 --- a/core/src/main/java/org/springframework/security/providers/cas/populator/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -Implementations that populate GrantedAuthority[]s of CAS authentications. - - diff --git a/core/src/test/java/org/springframework/security/providers/cas/CasAuthenticationProviderTests.java b/core/src/test/java/org/springframework/security/providers/cas/CasAuthenticationProviderTests.java index c8df46df39..2b9799f683 100644 --- a/core/src/test/java/org/springframework/security/providers/cas/CasAuthenticationProviderTests.java +++ b/core/src/test/java/org/springframework/security/providers/cas/CasAuthenticationProviderTests.java @@ -15,8 +15,6 @@ package org.springframework.security.providers.cas; -import junit.framework.TestCase; - import org.springframework.security.Authentication; import org.springframework.security.AuthenticationException; import org.springframework.security.BadCredentialsException; @@ -31,12 +29,16 @@ import org.springframework.security.ui.cas.CasProcessingFilter; import org.springframework.security.userdetails.User; import org.springframework.security.userdetails.UserDetails; +import org.springframework.security.userdetails.UserDetailsService; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Vector; +import org.junit.Test; +import static org.junit.Assert.*; + /** * Tests {@link CasAuthenticationProvider}. @@ -44,16 +46,7 @@ import java.util.Vector; * @author Ben Alex * @version $Id$ */ -public class CasAuthenticationProviderTests extends TestCase { - //~ Constructors =================================================================================================== - - public CasAuthenticationProviderTests() { - } - - public CasAuthenticationProviderTests(String arg0) { - super(arg0); - } - +public class CasAuthenticationProviderTests { //~ Methods ======================================================================================================== private UserDetails makeUserDetails() { @@ -66,13 +59,10 @@ public class CasAuthenticationProviderTests extends TestCase { new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A"), new GrantedAuthorityImpl("ROLE_B")}); } - public final void setUp() throws Exception { - super.setUp(); - } - - public void testAuthenticateStateful() throws Exception { + @Test + public void statefulAuthenticationIsSuccessful() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); - cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); + cap.setUserDetailsService(new MockAuthoritiesPopulator()); cap.setCasProxyDecider(new MockProxyDecider(true)); cap.setKey("qwerty"); @@ -111,9 +101,10 @@ public class CasAuthenticationProviderTests extends TestCase { assertEquals(result, laterResult); } - public void testAuthenticateStateless() throws Exception { + @Test + public void statelessAuthenticationIsSuccessful() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); - cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); + cap.setUserDetailsService(new MockAuthoritiesPopulator()); cap.setCasProxyDecider(new MockProxyDecider(true)); cap.setKey("qwerty"); @@ -147,9 +138,10 @@ public class CasAuthenticationProviderTests extends TestCase { assertEquals("ST-456", newResult.getCredentials()); } - public void testDetectsAMissingTicketId() throws Exception { + @Test(expected = BadCredentialsException.class) + public void missingTicketIdIsDetected() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); - cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); + cap.setUserDetailsService(new MockAuthoritiesPopulator()); cap.setCasProxyDecider(new MockProxyDecider(true)); cap.setKey("qwerty"); @@ -158,19 +150,16 @@ public class CasAuthenticationProviderTests extends TestCase { cap.setTicketValidator(new MockTicketValidator(true)); cap.afterPropertiesSet(); - UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(CasProcessingFilter.CAS_STATEFUL_IDENTIFIER, - ""); + UsernamePasswordAuthenticationToken token = + new UsernamePasswordAuthenticationToken(CasProcessingFilter.CAS_STATEFUL_IDENTIFIER, ""); - try { - Authentication result = cap.authenticate(token); - fail("Should have thrown BadCredentialsException"); - } catch (BadCredentialsException expected) { - } + Authentication result = cap.authenticate(token); } - public void testDetectsAnInvalidKey() throws Exception { + @Test(expected = BadCredentialsException.class) + public void invalidKeyIsDetected() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); - cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); + cap.setUserDetailsService(new MockAuthoritiesPopulator()); cap.setCasProxyDecider(new MockProxyDecider(true)); cap.setKey("qwerty"); @@ -182,112 +171,82 @@ public class CasAuthenticationProviderTests extends TestCase { CasAuthenticationToken token = new CasAuthenticationToken("WRONG_KEY", makeUserDetails(), "credentials", new GrantedAuthority[] {new GrantedAuthorityImpl("XX")}, makeUserDetails(), new Vector(), "IOU-xxx"); - try { - Authentication result = cap.authenticate(token); - fail("Should have thrown BadCredentialsException"); - } catch (BadCredentialsException expected) { - } + cap.authenticate(token); } - public void testDetectsMissingAuthoritiesPopulator() - throws Exception { + @Test(expected = IllegalArgumentException.class) + public void detectsMissingAuthoritiesPopulator() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); cap.setCasProxyDecider(new MockProxyDecider()); cap.setKey("qwerty"); cap.setStatelessTicketCache(new MockStatelessTicketCache()); cap.setTicketValidator(new MockTicketValidator(true)); - - try { - cap.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertEquals("A casAuthoritiesPopulator must be set", expected.getMessage()); - } + cap.afterPropertiesSet(); } - public void testDetectsMissingKey() throws Exception { + @Test(expected = IllegalArgumentException.class) + public void detectsMissingKey() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); - cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); + cap.setUserDetailsService(new MockAuthoritiesPopulator()); cap.setCasProxyDecider(new MockProxyDecider()); cap.setStatelessTicketCache(new MockStatelessTicketCache()); cap.setTicketValidator(new MockTicketValidator(true)); - - try { - cap.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertEquals("A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated", - expected.getMessage()); - } + cap.afterPropertiesSet(); } - public void testDetectsMissingProxyDecider() throws Exception { + @Test(expected = IllegalArgumentException.class) + public void detectsMissingProxyDecider() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); - cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); + cap.setUserDetailsService(new MockAuthoritiesPopulator()); cap.setKey("qwerty"); cap.setStatelessTicketCache(new MockStatelessTicketCache()); cap.setTicketValidator(new MockTicketValidator(true)); - - try { - cap.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertEquals("A casProxyDecider must be set", expected.getMessage()); - } + cap.afterPropertiesSet(); } - public void testDetectsMissingStatelessTicketCache() - throws Exception { + @Test(expected = IllegalArgumentException.class) + public void detectsMissingStatelessTicketCache() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); // set this explicitly to null to test failure cap.setStatelessTicketCache(null); - cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); + cap.setUserDetailsService(new MockAuthoritiesPopulator()); cap.setCasProxyDecider(new MockProxyDecider()); cap.setKey("qwerty"); cap.setTicketValidator(new MockTicketValidator(true)); - - try { - cap.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertEquals("A statelessTicketCache must be set", expected.getMessage()); - } + cap.afterPropertiesSet(); } - public void testDetectsMissingTicketValidator() throws Exception { + @Test(expected = IllegalArgumentException.class) + public void detectsMissingTicketValidator() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); - cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); + cap.setUserDetailsService(new MockAuthoritiesPopulator()); cap.setCasProxyDecider(new MockProxyDecider(true)); cap.setKey("qwerty"); cap.setStatelessTicketCache(new MockStatelessTicketCache()); - - try { - cap.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertEquals("A ticketValidator must be set", expected.getMessage()); - } + cap.afterPropertiesSet(); } - public void testGettersSetters() throws Exception { + @Test + public void gettersAndSettersMatch() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); - cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); + cap.setUserDetailsService(new MockAuthoritiesPopulator()); cap.setCasProxyDecider(new MockProxyDecider()); cap.setKey("qwerty"); cap.setStatelessTicketCache(new MockStatelessTicketCache()); cap.setTicketValidator(new MockTicketValidator(true)); cap.afterPropertiesSet(); - assertTrue(cap.getCasAuthoritiesPopulator() != null); + assertTrue(cap.getUserDetailsService() != null); assertTrue(cap.getCasProxyDecider() != null); assertEquals("qwerty", cap.getKey()); assertTrue(cap.getStatelessTicketCache() != null); assertTrue(cap.getTicketValidator() != null); } - public void testIgnoresClassesItDoesNotSupport() throws Exception { + @Test + public void ignoresClassesItDoesNotSupport() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); - cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); + cap.setUserDetailsService(new MockAuthoritiesPopulator()); cap.setCasProxyDecider(new MockProxyDecider()); cap.setKey("qwerty"); cap.setStatelessTicketCache(new MockStatelessTicketCache()); @@ -302,10 +261,10 @@ public class CasAuthenticationProviderTests extends TestCase { assertEquals(null, cap.authenticate(token)); } - public void testIgnoresUsernamePasswordAuthenticationTokensWithoutCasIdentifiersAsPrincipal() - throws Exception { + @Test + public void ignoresUsernamePasswordAuthenticationTokensWithoutCasIdentifiersAsPrincipal() throws Exception { CasAuthenticationProvider cap = new CasAuthenticationProvider(); - cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); + cap.setUserDetailsService(new MockAuthoritiesPopulator()); cap.setCasProxyDecider(new MockProxyDecider()); cap.setKey("qwerty"); cap.setStatelessTicketCache(new MockStatelessTicketCache()); @@ -317,7 +276,8 @@ public class CasAuthenticationProviderTests extends TestCase { assertEquals(null, cap.authenticate(token)); } - public void testSupports() { + @Test + public void supportsRequiredTokens() { CasAuthenticationProvider cap = new CasAuthenticationProvider(); assertTrue(cap.supports(UsernamePasswordAuthenticationToken.class)); assertTrue(cap.supports(CasAuthenticationToken.class)); @@ -325,9 +285,8 @@ public class CasAuthenticationProviderTests extends TestCase { //~ Inner Classes ================================================================================================== - private class MockAuthoritiesPopulator implements CasAuthoritiesPopulator { - public UserDetails getUserDetails(String casUserId) - throws AuthenticationException { + private class MockAuthoritiesPopulator implements UserDetailsService { + public UserDetails loadUserByUsername(String casUserId) throws AuthenticationException { return makeUserDetailsFromAuthoritiesPopulator(); } } @@ -380,10 +339,6 @@ public class CasAuthenticationProviderTests extends TestCase { this.returnTicket = returnTicket; } - private MockTicketValidator() { - super(); - } - public TicketResponse confirmTicketValid(String serviceTicket) throws AuthenticationException { if (returnTicket) { diff --git a/core/src/test/java/org/springframework/security/providers/cas/populator/DaoCasAuthoritiesPopulatorTests.java b/core/src/test/java/org/springframework/security/providers/cas/populator/DaoCasAuthoritiesPopulatorTests.java deleted file mode 100644 index ca0842e92b..0000000000 --- a/core/src/test/java/org/springframework/security/providers/cas/populator/DaoCasAuthoritiesPopulatorTests.java +++ /dev/null @@ -1,145 +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.providers.cas.populator; - -import junit.framework.TestCase; - -import org.springframework.security.GrantedAuthority; -import org.springframework.security.GrantedAuthorityImpl; - -import org.springframework.security.userdetails.User; -import org.springframework.security.userdetails.UserDetails; -import org.springframework.security.userdetails.UserDetailsService; -import org.springframework.security.userdetails.UsernameNotFoundException; - -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataRetrievalFailureException; - - -/** - * Tests {@link DaoCasAuthoritiesPopulator}. - * - * @author Ben Alex - * @version $Id$ - */ -public class DaoCasAuthoritiesPopulatorTests extends TestCase { - //~ Constructors =================================================================================================== - - public DaoCasAuthoritiesPopulatorTests() { - super(); - } - - public DaoCasAuthoritiesPopulatorTests(String arg0) { - super(arg0); - } - - //~ Methods ======================================================================================================== - - public static void main(String[] args) { - junit.textui.TestRunner.run(DaoCasAuthoritiesPopulatorTests.class); - } - - public final void setUp() throws Exception { - super.setUp(); - } - - public void testDetectsMissingAuthenticationDao() throws Exception { - DaoCasAuthoritiesPopulator populator = new DaoCasAuthoritiesPopulator(); - - try { - populator.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertEquals("A UserDetailsService must be set", expected.getMessage()); - } - } - - public void testGetGrantedAuthoritiesForInvalidUsername() - throws Exception { - DaoCasAuthoritiesPopulator populator = new DaoCasAuthoritiesPopulator(); - populator.setUserDetailsService(new MockAuthenticationDaoUserrod()); - populator.afterPropertiesSet(); - - try { - populator.getUserDetails("scott"); - fail("Should have thrown UsernameNotFoundException"); - } catch (UsernameNotFoundException expected) { - assertTrue(true); - } - } - - public void testGetGrantedAuthoritiesForValidUsername() - throws Exception { - DaoCasAuthoritiesPopulator populator = new DaoCasAuthoritiesPopulator(); - populator.setUserDetailsService(new MockAuthenticationDaoUserrod()); - populator.afterPropertiesSet(); - - UserDetails results = populator.getUserDetails("rod"); - assertEquals(2, results.getAuthorities().length); - assertEquals(new GrantedAuthorityImpl("ROLE_ONE"), results.getAuthorities()[0]); - assertEquals(new GrantedAuthorityImpl("ROLE_TWO"), results.getAuthorities()[1]); - } - - public void testGetGrantedAuthoritiesWhenDaoThrowsException() - throws Exception { - DaoCasAuthoritiesPopulator populator = new DaoCasAuthoritiesPopulator(); - populator.setUserDetailsService(new MockAuthenticationDaoSimulateBackendError()); - populator.afterPropertiesSet(); - - try { - populator.getUserDetails("THE_DAO_WILL_FAIL"); - fail("Should have thrown DataRetrievalFailureException"); - } catch (DataRetrievalFailureException expected) { - assertTrue(true); - } - } - - public void testGettersSetters() { - DaoCasAuthoritiesPopulator populator = new DaoCasAuthoritiesPopulator(); - UserDetailsService dao = new MockAuthenticationDaoUserrod(); - populator.setUserDetailsService(dao); - assertEquals(dao, populator.getUserDetailsService()); - } - - //~ Inner Classes ================================================================================================== - - private class MockAuthenticationDaoSimulateBackendError implements UserDetailsService { - public long getRefreshDuration() { - return 0; - } - - public UserDetails loadUserByUsername(String username) - throws UsernameNotFoundException, DataAccessException { - throw new DataRetrievalFailureException("This mock simulator is designed to fail"); - } - } - - private class MockAuthenticationDaoUserrod implements UserDetailsService { - public long getRefreshDuration() { - return 0; - } - - public UserDetails loadUserByUsername(String username) - throws UsernameNotFoundException, DataAccessException { - if ("rod".equals(username)) { - return new User("rod", "koala", true, true, true, true, - new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); - } else { - throw new UsernameNotFoundException("Could not find: " + username); - } - } - } -} diff --git a/openid/src/main/java/org/springframework/security/providers/openid/OpenIDAuthenticationProvider.java b/openid/src/main/java/org/springframework/security/providers/openid/OpenIDAuthenticationProvider.java index d42e44922e..101089f7f7 100644 --- a/openid/src/main/java/org/springframework/security/providers/openid/OpenIDAuthenticationProvider.java +++ b/openid/src/main/java/org/springframework/security/providers/openid/OpenIDAuthenticationProvider.java @@ -20,32 +20,43 @@ import org.springframework.security.AuthenticationException; import org.springframework.security.AuthenticationServiceException; import org.springframework.security.BadCredentialsException; import org.springframework.security.providers.AuthenticationProvider; -import org.springframework.security.providers.AuthoritiesPopulator; import org.springframework.security.userdetails.UserDetails; +import org.springframework.security.userdetails.UserDetailsService; import org.springframework.util.Assert; /** - * Finalises the OpenID authentication by obtaining local roles + * Finalises the OpenID authentication by obtaining local authorities for the authenticated user. + *
+ * The authorities are obtained by calling the configured UserDetailsService.
+ * The UserDetails it returns must, at minimum, contain the username and GrantedAuthority[]
+ * objects applicable to the authenticated user. Note that by default, Spring Security ignores the password and
+ * enabled/disabled status of the UserDetails because this is
+ * authentication-related and should have been enforced by another provider server.
+ *
+ * You can optionally have these checked by configuring wrapping the UserDetailsService in a + * {@link org.springframework.security.userdetails.decorator.StatusCheckingUserDetailsService} decorator. + *
+ * The UserDetails returned by implementations is stored in the generated AuthenticationToken,
+ * so additional properties such as email addresses, telephone numbers etc can easily be stored.
*
* @author Robin Bramley, Opsera Ltd.
*/
public class OpenIDAuthenticationProvider implements AuthenticationProvider, InitializingBean {
//~ Instance fields ================================================================================================
- private AuthoritiesPopulator authoritiesPopulator;
+ private UserDetailsService userDetailsService;
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
- Assert.notNull(this.authoritiesPopulator, "The authoritiesPopulator must be set");
+ Assert.notNull(this.userDetailsService, "The userDetailsService must be set");
}
/* (non-Javadoc)
* @see org.springframework.security.providers.AuthenticationProvider#authenticate(org.springframework.security.Authentication)
*/
- public Authentication authenticate(final Authentication authentication)
- throws AuthenticationException {
+ public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
if (!supports(authentication.getClass())) {
return null;
@@ -59,7 +70,7 @@ public class OpenIDAuthenticationProvider implements AuthenticationProvider, Ini
if (status == OpenIDAuthenticationStatus.SUCCESS) {
// Lookup user details
- UserDetails userDetails = this.authoritiesPopulator.getUserDetails(response.getIdentityUrl());
+ UserDetails userDetails = userDetailsService.loadUserByUsername(response.getIdentityUrl());
return new OpenIDAuthenticationToken(userDetails.getAuthorities(), response.getStatus(),
response.getIdentityUrl());
@@ -81,8 +92,11 @@ public class OpenIDAuthenticationProvider implements AuthenticationProvider, Ini
return null;
}
- public void setAuthoritiesPopulator(AuthoritiesPopulator authoritiesPopulator) {
- this.authoritiesPopulator = authoritiesPopulator;
+ /**
+ * Used to load the authorities for the authenticated OpenID user.
+ */
+ public void setUserDetailsService(UserDetailsService userDetailsService) {
+ this.userDetailsService = userDetailsService;
}
/* (non-Javadoc)
diff --git a/openid/src/main/java/org/springframework/security/providers/openid/OpenIDAuthenticationToken.java b/openid/src/main/java/org/springframework/security/providers/openid/OpenIDAuthenticationToken.java
index f9aac0a772..28254c3b7f 100644
--- a/openid/src/main/java/org/springframework/security/providers/openid/OpenIDAuthenticationToken.java
+++ b/openid/src/main/java/org/springframework/security/providers/openid/OpenIDAuthenticationToken.java
@@ -41,13 +41,10 @@ public class OpenIDAuthenticationToken extends AbstractAuthenticationToken {
setAuthenticated(false);
}
-/**
+ /**
* Created by the OpenIDAuthenticationProvider on successful authentication.
* Do not use directly
*
- * @param authorities
- * @param status
- * @param identityUrl
*/
public OpenIDAuthenticationToken(GrantedAuthority[] authorities, OpenIDAuthenticationStatus status, String identityUrl) {
super(authorities);
diff --git a/openid/src/test/java/org/springframework/security/providers/openid/MockAuthoritiesPopulator.java b/openid/src/test/java/org/springframework/security/providers/openid/MockAuthoritiesPopulator.java
deleted file mode 100644
index 6acce17c53..0000000000
--- a/openid/src/test/java/org/springframework/security/providers/openid/MockAuthoritiesPopulator.java
+++ /dev/null
@@ -1,38 +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.providers.openid;
-
-import org.springframework.security.AuthenticationException;
-import org.springframework.security.GrantedAuthority;
-import org.springframework.security.GrantedAuthorityImpl;
-import org.springframework.security.providers.AuthoritiesPopulator;
-import org.springframework.security.userdetails.User;
-import org.springframework.security.userdetails.UserDetails;
-
-
-/**
- * DOCUMENT ME!
- *
- * @author Robin Bramley, Opsera Ltd
- */
-public class MockAuthoritiesPopulator implements AuthoritiesPopulator {
- //~ Methods ========================================================================================================
-
- public UserDetails getUserDetails(String ssoUserId)
- throws AuthenticationException {
- return new User(ssoUserId, "password", true, true, true, true,
- new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A"), new GrantedAuthorityImpl("ROLE_B")});
- }
-}
diff --git a/openid/src/test/java/org/springframework/security/providers/openid/OpenIDAuthenticationProviderTests.java b/openid/src/test/java/org/springframework/security/providers/openid/OpenIDAuthenticationProviderTests.java
index 5a8871b1df..58dcb2d586 100644
--- a/openid/src/test/java/org/springframework/security/providers/openid/OpenIDAuthenticationProviderTests.java
+++ b/openid/src/test/java/org/springframework/security/providers/openid/OpenIDAuthenticationProviderTests.java
@@ -18,7 +18,13 @@ import junit.framework.TestCase;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationServiceException;
import org.springframework.security.BadCredentialsException;
+import org.springframework.security.AuthenticationException;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.security.userdetails.User;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
+import org.springframework.security.userdetails.UserDetailsService;
/**
@@ -38,7 +44,7 @@ public class OpenIDAuthenticationProviderTests extends TestCase {
*/
public void testAuthenticateCancel() {
OpenIDAuthenticationProvider provider = new OpenIDAuthenticationProvider();
- provider.setAuthoritiesPopulator(new MockAuthoritiesPopulator());
+ provider.setUserDetailsService(new MockUserDetailsService());
Authentication preAuth = new OpenIDAuthenticationToken(OpenIDAuthenticationStatus.CANCELLED, USERNAME, "");
@@ -57,7 +63,7 @@ public class OpenIDAuthenticationProviderTests extends TestCase {
*/
public void testAuthenticateError() {
OpenIDAuthenticationProvider provider = new OpenIDAuthenticationProvider();
- provider.setAuthoritiesPopulator(new MockAuthoritiesPopulator());
+ provider.setUserDetailsService(new MockUserDetailsService());
Authentication preAuth = new OpenIDAuthenticationToken(OpenIDAuthenticationStatus.ERROR, USERNAME, "");
@@ -76,7 +82,7 @@ public class OpenIDAuthenticationProviderTests extends TestCase {
*/
public void testAuthenticateFailure() {
OpenIDAuthenticationProvider provider = new OpenIDAuthenticationProvider();
- provider.setAuthoritiesPopulator(new MockAuthoritiesPopulator());
+ provider.setUserDetailsService(new MockUserDetailsService());
Authentication preAuth = new OpenIDAuthenticationToken(OpenIDAuthenticationStatus.FAILURE, USERNAME, "");
@@ -95,7 +101,7 @@ public class OpenIDAuthenticationProviderTests extends TestCase {
*/
public void testAuthenticateSetupNeeded() {
OpenIDAuthenticationProvider provider = new OpenIDAuthenticationProvider();
- provider.setAuthoritiesPopulator(new MockAuthoritiesPopulator());
+ provider.setUserDetailsService(new MockUserDetailsService());
Authentication preAuth = new OpenIDAuthenticationToken(OpenIDAuthenticationStatus.SETUP_NEEDED, USERNAME, "");
@@ -114,7 +120,7 @@ public class OpenIDAuthenticationProviderTests extends TestCase {
*/
public void testAuthenticateSuccess() {
OpenIDAuthenticationProvider provider = new OpenIDAuthenticationProvider();
- provider.setAuthoritiesPopulator(new MockAuthoritiesPopulator());
+ provider.setUserDetailsService(new MockUserDetailsService());
Authentication preAuth = new OpenIDAuthenticationToken(OpenIDAuthenticationStatus.SUCCESS, USERNAME, "");
@@ -149,7 +155,7 @@ public class OpenIDAuthenticationProviderTests extends TestCase {
*/
public void testDoesntSupport() {
OpenIDAuthenticationProvider provider = new OpenIDAuthenticationProvider();
- provider.setAuthoritiesPopulator(new MockAuthoritiesPopulator());
+ provider.setUserDetailsService(new MockUserDetailsService());
assertFalse(provider.supports(UsernamePasswordAuthenticationToken.class));
}
@@ -159,7 +165,7 @@ public class OpenIDAuthenticationProviderTests extends TestCase {
*/
public void testIgnoresUserPassAuthToken() {
OpenIDAuthenticationProvider provider = new OpenIDAuthenticationProvider();
- provider.setAuthoritiesPopulator(new MockAuthoritiesPopulator());
+ provider.setUserDetailsService(new MockUserDetailsService());
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(USERNAME, "password");
assertEquals(null, provider.authenticate(token));
@@ -170,17 +176,17 @@ public class OpenIDAuthenticationProviderTests extends TestCase {
*/
public void testSupports() {
OpenIDAuthenticationProvider provider = new OpenIDAuthenticationProvider();
- provider.setAuthoritiesPopulator(new MockAuthoritiesPopulator());
+ provider.setUserDetailsService(new MockUserDetailsService());
assertTrue(provider.supports(OpenIDAuthenticationToken.class));
}
public void testValidation() throws Exception {
OpenIDAuthenticationProvider provider = new OpenIDAuthenticationProvider();
- provider.setAuthoritiesPopulator(new MockAuthoritiesPopulator());
+ provider.setUserDetailsService(new MockUserDetailsService());
provider.afterPropertiesSet();
- provider.setAuthoritiesPopulator(null);
+ provider.setUserDetailsService(null);
try {
provider.afterPropertiesSet();
@@ -189,4 +195,12 @@ public class OpenIDAuthenticationProviderTests extends TestCase {
//expected
}
}
+
+ static class MockUserDetailsService implements UserDetailsService {
+ public UserDetails loadUserByUsername(String ssoUserId)
+ throws AuthenticationException {
+ return new User(ssoUserId, "password", true, true, true, true,
+ new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A"), new GrantedAuthorityImpl("ROLE_B")});
+ }
+ }
}
diff --git a/portlet/src/main/java/org/springframework/security/providers/portlet/PortletAuthenticationProvider.java b/portlet/src/main/java/org/springframework/security/providers/portlet/PortletAuthenticationProvider.java
index 4a8efb07e8..9993653ef9 100644
--- a/portlet/src/main/java/org/springframework/security/providers/portlet/PortletAuthenticationProvider.java
+++ b/portlet/src/main/java/org/springframework/security/providers/portlet/PortletAuthenticationProvider.java
@@ -65,7 +65,7 @@ public class PortletAuthenticationProvider
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
- Assert.notNull(this.portletAuthoritiesPopulator, "An authorities populator must be set");
+ Assert.notNull(this.portletAuthoritiesPopulator, "An authorities populator must be set");
Assert.notNull(this.userCache, "A user cache must be set");
}
diff --git a/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml b/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml
index f09786d705..a230c88480 100644
--- a/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml
+++ b/samples/openid/src/main/webapp/WEB-INF/applicationContext-security.xml
@@ -29,11 +29,7 @@