SWS-972 - Handle UserDetailsService not finding user

SpringSecurityPasswordValidationCallbackHandler throws NPE when UserDetailsService does not find user. This adds a null check and additional test cases.
This commit is contained in:
Jamin Hitchcock
2017-08-16 22:02:37 -05:00
committed by Greg Turnquist
parent eaa5bba391
commit 8d412d2c84
2 changed files with 42 additions and 2 deletions

View File

@@ -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
* <p>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

View File

@@ -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