diff --git a/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j2/callback/SpringSecurityPasswordValidationCallbackHandler.java b/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j2/callback/SpringSecurityPasswordValidationCallbackHandler.java index 4961e8b2..fa1e5efe 100644 --- a/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j2/callback/SpringSecurityPasswordValidationCallbackHandler.java +++ b/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j2/callback/SpringSecurityPasswordValidationCallbackHandler.java @@ -33,6 +33,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.cache.NullUserCache; import org.springframework.util.Assert; import org.springframework.ws.soap.security.callback.CleanupCallback; +import org.springframework.ws.soap.security.support.SpringSecurityUtils; /** * Callback handler that validates a plain text or digest password using an Spring Security {@code UserDetailsService}. @@ -76,8 +77,11 @@ public class SpringSecurityPasswordValidationCallbackHandler extends AbstractWsP *

Default implementation throws an {@link UnsupportedCallbackException}. */ protected void handleUsernameToken(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException { - UserDetails details = loadUserDetails(callback.getIdentifier()); - callback.setPassword(details.getPassword()); + UserDetails user = loadUserDetails(callback.getIdentifier()); + if (user != null) { + SpringSecurityUtils.checkUserValidity(user); + callback.setPassword(user.getPassword()); + } } @Override diff --git a/spring-ws-security/src/test/java/org/springframework/ws/soap/security/wss4j2/callback/SpringSecurityPasswordValidationCallbackHandlerTest.java b/spring-ws-security/src/test/java/org/springframework/ws/soap/security/wss4j2/callback/SpringSecurityPasswordValidationCallbackHandlerTest.java index e3b076d0..11d317ba 100644 --- a/spring-ws-security/src/test/java/org/springframework/ws/soap/security/wss4j2/callback/SpringSecurityPasswordValidationCallbackHandlerTest.java +++ b/spring-ws-security/src/test/java/org/springframework/ws/soap/security/wss4j2/callback/SpringSecurityPasswordValidationCallbackHandlerTest.java @@ -27,6 +27,8 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.apache.wss4j.common.ext.WSPasswordCallback; import org.apache.wss4j.common.principal.WSUsernameTokenPrincipalImpl; import org.junit.Assert; import org.junit.Before; @@ -42,6 +44,8 @@ public class SpringSecurityPasswordValidationCallbackHandlerTest { private SimpleGrantedAuthority grantedAuthority; private UsernameTokenPrincipalCallback callback; + + private WSPasswordCallback passwordCallback; private UserDetails user; @@ -54,6 +58,38 @@ public class SpringSecurityPasswordValidationCallbackHandlerTest { WSUsernameTokenPrincipalImpl principal = new WSUsernameTokenPrincipalImpl("Ernie", true); callback = new UsernameTokenPrincipalCallback(principal); + + passwordCallback = new WSPasswordCallback("Ernie", null, "type", WSPasswordCallback.USERNAME_TOKEN); + } + + @Test + public void testHandleUsernameToken() throws Exception { + UserDetailsService userDetailsService = createMock(UserDetailsService.class); + callbackHandler.setUserDetailsService(userDetailsService); + + expect(userDetailsService.loadUserByUsername("Ernie")).andReturn(user).anyTimes(); + + replay(userDetailsService); + + callbackHandler.handleUsernameToken(passwordCallback); + Assert.assertEquals("Bert", passwordCallback.getPassword()); + + verify(userDetailsService); + } + + @Test + public void testHandleUsernameTokenUserNotFound() throws Exception { + UserDetailsService userDetailsService = createMock(UserDetailsService.class); + callbackHandler.setUserDetailsService(userDetailsService); + + expect(userDetailsService.loadUserByUsername("Ernie")).andThrow(new UsernameNotFoundException("User 'Ernie' not found")); + + replay(userDetailsService); + + callbackHandler.handleUsernameToken(passwordCallback); + Assert.assertNull(passwordCallback.getPassword()); + + verify(userDetailsService); } @Test