mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-25 21:42:17 +00:00
SEC-536: Added UserDetailsService decorator class which will throw an appropriate exception if the returned UserDetails object has a status of locked, disabled etc.
This commit is contained in:
parent
f0c15f5b1a
commit
c9dee10704
@ -0,0 +1,58 @@
|
||||
package org.springframework.security.userdetails.decorator;
|
||||
|
||||
import org.springframework.security.userdetails.UserDetailsService;
|
||||
import org.springframework.security.userdetails.UserDetails;
|
||||
import org.springframework.security.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.LockedException;
|
||||
import org.springframework.security.DisabledException;
|
||||
import org.springframework.security.AccountExpiredException;
|
||||
import org.springframework.security.CredentialsExpiredException;
|
||||
import org.springframework.security.SpringSecurityMessageSource;
|
||||
import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Decorates a {@link UserDetailsService}, making it throw an exception if the account is locked, disabled etc. This
|
||||
* removes the need for separate account status checks in classes which make use of a <tt>UserDetailsService</tt>.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
*/
|
||||
public class StatusCheckingUserDetailsService implements UserDetailsService {
|
||||
private UserDetailsService delegate;
|
||||
|
||||
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||
|
||||
public StatusCheckingUserDetailsService(UserDetailsService userDetailsService) {
|
||||
this.delegate = userDetailsService;
|
||||
}
|
||||
|
||||
public UserDetails loadUserByUsername(String username) throws AuthenticationException, DataAccessException {
|
||||
|
||||
UserDetails user = delegate.loadUserByUsername(username);
|
||||
|
||||
Assert.notNull(user, "UserDetailsService returned null user, an interface violation.");
|
||||
|
||||
if (!user.isAccountNonLocked()) {
|
||||
throw new LockedException(messages.getMessage("UserDetailsService.locked", "User account is locked"));
|
||||
}
|
||||
|
||||
if (!user.isEnabled()) {
|
||||
throw new DisabledException(messages.getMessage("UserDetailsService.disabled", "User is disabled"));
|
||||
}
|
||||
|
||||
if (!user.isAccountNonExpired()) {
|
||||
throw new AccountExpiredException(messages.getMessage("UserDetailsService.expired",
|
||||
"User account has expired"));
|
||||
}
|
||||
|
||||
if (!user.isCredentialsNonExpired()) {
|
||||
throw new CredentialsExpiredException(messages.getMessage("UserDetailsService.credentialsExpired",
|
||||
"User credentials have expired"));
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package org.springframework.security.userdetails.decorator;
|
||||
|
||||
import org.springframework.security.userdetails.UserDetailsService;
|
||||
import org.springframework.security.userdetails.UserDetails;
|
||||
import org.springframework.security.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.userdetails.User;
|
||||
import org.springframework.security.GrantedAuthority;
|
||||
import org.springframework.security.GrantedAuthorityImpl;
|
||||
import org.springframework.security.LockedException;
|
||||
import org.springframework.security.DisabledException;
|
||||
import org.springframework.security.CredentialsExpiredException;
|
||||
import org.springframework.security.AccountExpiredException;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
*/
|
||||
public class StatusCheckingUserDetailsServiceTests {
|
||||
private StatusCheckingUserDetailsService us = new StatusCheckingUserDetailsService(new MockUserDetailsService());
|
||||
|
||||
@Test
|
||||
public void validAccountIsSuccessfullyLoaded() throws Exception {
|
||||
us.loadUserByUsername("valid");
|
||||
}
|
||||
|
||||
@Test(expected = LockedException.class)
|
||||
public void lockedAccountThrowsLockedException() throws Exception {
|
||||
us.loadUserByUsername("locked");
|
||||
}
|
||||
|
||||
@Test(expected = DisabledException.class)
|
||||
public void disabledAccountThrowsDisabledException() throws Exception {
|
||||
us.loadUserByUsername("disabled");
|
||||
}
|
||||
|
||||
@Test(expected = CredentialsExpiredException.class)
|
||||
public void credentialsExpiredAccountThrowsCredentialsExpiredException() throws Exception {
|
||||
us.loadUserByUsername("credentialsExpired");
|
||||
}
|
||||
|
||||
@Test(expected = AccountExpiredException.class)
|
||||
public void expiredAccountThrowsAccountExpiredException() throws Exception {
|
||||
us.loadUserByUsername("expired");
|
||||
}
|
||||
|
||||
class MockUserDetailsService implements UserDetailsService {
|
||||
private Map <String, UserDetails> users = new HashMap <String, UserDetails>();
|
||||
private GrantedAuthority[] auths = new GrantedAuthority[] {new GrantedAuthorityImpl("A")};
|
||||
|
||||
MockUserDetailsService() {
|
||||
users.put("valid", new User("valid", "",true,true,true,true,auths));
|
||||
users.put("locked", new User("locked", "",true,true,true,false,auths));
|
||||
users.put("disabled", new User("disabled", "",false,true,true,true,auths));
|
||||
users.put("credentialsExpired", new User("credentialsExpired", "",true,true,false,true,auths));
|
||||
users.put("expired", new User("expired", "",true,false,true,true,auths));
|
||||
}
|
||||
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
|
||||
return users.get(username);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user