diff --git a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosAuthenticationProvider.java b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosAuthenticationProvider.java index 9558037..0b553f7 100644 --- a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosAuthenticationProvider.java +++ b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosAuthenticationProvider.java @@ -44,6 +44,7 @@ public class KerberosAuthenticationProvider implements AuthenticationProvider { String validatedUsername = kerberosClient.login(auth.getName(), auth.getCredentials().toString()); UserDetails userDetails = this.userDetailsService.loadUserByUsername(validatedUsername); UsernamePasswordAuthenticationToken output = new UsernamePasswordAuthenticationToken(userDetails, auth.getCredentials(), userDetails.getAuthorities()); + output.setDetails(authentication.getDetails()); return output; } diff --git a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProvider.java b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProvider.java index 2868c48..575919e 100644 --- a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProvider.java +++ b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProvider.java @@ -87,7 +87,10 @@ public class KerberosServiceAuthenticationProvider implements UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); userDetailsChecker.check(userDetails); additionalAuthenticationChecks(userDetails, auth); - return new KerberosServiceRequestToken(userDetails, userDetails.getAuthorities(), token); + KerberosServiceRequestToken responseAuth = new KerberosServiceRequestToken(userDetails, userDetails.getAuthorities(), token); + responseAuth.setDetails(authentication.getDetails()); + return responseAuth; + } diff --git a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilter.java b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilter.java index 580fa81..8a2fcff 100644 --- a/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilter.java +++ b/spring-security-kerberos-core/src/main/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilter.java @@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -36,6 +37,7 @@ import org.springframework.security.extensions.kerberos.KerberosServiceRequestTo import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; import org.springframework.util.Assert; @@ -109,7 +111,8 @@ import org.springframework.web.filter.GenericFilterBean; * @see SpnegoEntryPoint */ public class SpnegoAuthenticationProcessingFilter extends GenericFilterBean { - + + private AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource(); private AuthenticationManager authenticationManager; private AuthenticationSuccessHandler successHandler; private AuthenticationFailureHandler failureHandler; @@ -146,6 +149,7 @@ public class SpnegoAuthenticationProcessingFilter extends GenericFilterBean { byte[] base64Token = header.substring(10).getBytes("UTF-8"); byte[] kerberosTicket = Base64.decode(base64Token); KerberosServiceRequestToken authenticationRequest = new KerberosServiceRequestToken(kerberosTicket); + authenticationRequest.setDetails(authenticationDetailsSource.buildDetails(request)); Authentication authentication; try { authentication = authenticationManager.authenticate(authenticationRequest); @@ -230,6 +234,12 @@ public class SpnegoAuthenticationProcessingFilter extends GenericFilterBean { public void setSessionAuthenticationStrategy(SessionAuthenticationStrategy sessionStrategy) { this.sessionStrategy = sessionStrategy; } + + + public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) { + Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); + this.authenticationDetailsSource = authenticationDetailsSource; + } /* * (non-Javadoc) diff --git a/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProviderTest.java b/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProviderTest.java index caf72d8..978ca29 100644 --- a/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProviderTest.java +++ b/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/KerberosServiceAuthenticationProviderTest.java @@ -68,35 +68,44 @@ public class KerberosServiceAuthenticationProviderTest { @Test public void testEverythingWorks() throws Exception { - Authentication output = callProviderAndReturnUser(USER_DETAILS); + Authentication output = callProviderAndReturnUser(USER_DETAILS, INPUT_TOKEN); assertNotNull(output); assertEquals(TEST_USER, output.getName()); assertEquals(AUTHORITY_LIST, output.getAuthorities()); assertEquals(USER_DETAILS, output.getPrincipal()); } + + @Test + public void testAuthenticationDetailsPropagation() throws Exception { + KerberosServiceRequestToken requestToken = new KerberosServiceRequestToken(TEST_TOKEN); + requestToken.setDetails("TestDetails"); + Authentication output = callProviderAndReturnUser(USER_DETAILS, requestToken); + assertNotNull(output); + assertEquals(requestToken.getDetails(), output.getDetails()); + } @Test(expected=DisabledException.class) public void testUserIsDisabled() throws Exception { User disabledUser = new User(TEST_USER, "empty", false, true, true,true, AUTHORITY_LIST); - callProviderAndReturnUser(disabledUser); + callProviderAndReturnUser(disabledUser, INPUT_TOKEN); } @Test(expected=AccountExpiredException.class) public void testUserAccountIsExpired() throws Exception { User expiredUser = new User(TEST_USER, "empty", true, false, true,true, AUTHORITY_LIST); - callProviderAndReturnUser(expiredUser); + callProviderAndReturnUser(expiredUser, INPUT_TOKEN); } @Test(expected=CredentialsExpiredException.class) public void testUserCredentialsExpired() throws Exception { User credExpiredUser = new User(TEST_USER, "empty", true, true, false ,true, AUTHORITY_LIST); - callProviderAndReturnUser(credExpiredUser); + callProviderAndReturnUser(credExpiredUser, INPUT_TOKEN); } @Test(expected=LockedException.class) public void testUserAccountLockedCredentialsExpired() throws Exception { User lockedUser = new User(TEST_USER, "empty", true, true, true ,false, AUTHORITY_LIST); - callProviderAndReturnUser(lockedUser); + callProviderAndReturnUser(lockedUser, INPUT_TOKEN); } @Test(expected=UsernameNotFoundException.class) @@ -119,13 +128,13 @@ public class KerberosServiceAuthenticationProviderTest { provider.authenticate(INPUT_TOKEN); } - private Authentication callProviderAndReturnUser(UserDetails disabledUser) { + private Authentication callProviderAndReturnUser(UserDetails userDetails, Authentication inputToken) { // stubbing when(ticketValidator.validateTicket(TEST_TOKEN)).thenReturn(TEST_USER); - when(userDetailsService.loadUserByUsername(TEST_USER)).thenReturn(disabledUser); + when(userDetailsService.loadUserByUsername(TEST_USER)).thenReturn(userDetails); // testing - return provider.authenticate(INPUT_TOKEN); + return provider.authenticate(inputToken); } } diff --git a/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java b/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java index 0b804a9..5c0dfc2 100644 --- a/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java +++ b/spring-security-kerberos-core/src/test/java/org/springframework/security/extensions/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java @@ -41,6 +41,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.extensions.kerberos.KerberosServiceRequestToken; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; /** * Test class for {@link SpnegoAuthenticationProcessingFilter} @@ -58,6 +59,7 @@ public class SpnegoAuthenticationProcessingFilterTest { private FilterChain chain; private AuthenticationSuccessHandler successHandler; private AuthenticationFailureHandler failureHandler; + private WebAuthenticationDetailsSource detailsSource; // data private static final byte[] TEST_TOKEN = "TestToken".getBytes(); @@ -72,6 +74,7 @@ public class SpnegoAuthenticationProcessingFilterTest { public void before() throws Exception { // mocking authenticationManager = mock(AuthenticationManager.class); + detailsSource = new WebAuthenticationDetailsSource(); filter = new SpnegoAuthenticationProcessingFilter(); filter.setAuthenticationManager(authenticationManager); request = mock(HttpServletRequest.class); @@ -97,7 +100,9 @@ public class SpnegoAuthenticationProcessingFilterTest { private void everythingWorks() throws IOException, ServletException { // stubbing when(request.getHeader(HEADER)).thenReturn(TOKEN_PREFIX + TEST_TOKEN_BASE64); - when(authenticationManager.authenticate(new KerberosServiceRequestToken(TEST_TOKEN))).thenReturn(AUTHENTICATION); + KerberosServiceRequestToken requestToken = new KerberosServiceRequestToken(TEST_TOKEN); + requestToken.setDetails(detailsSource.buildDetails(request)); + when(authenticationManager.authenticate(requestToken)).thenReturn(AUTHENTICATION); // testing filter.doFilter(request, response, chain);