package edu.zzuli.common.security;
import org.acegisecurity.AccountExpiredException;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationServiceException;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.CredentialsExpiredException;
import org.acegisecurity.DisabledException;
import org.acegisecurity.LockedException;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.dao.DaoAuthenticationProvider;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.springframework.dao.DataAccessException;
import org.springframework.util.Assert;
public class CustomDaoAuthenticationProvider extends DaoAuthenticationProvider {
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
if (!(authentication instanceof CustomUsernamePasswordAuthenticationToken)&&!(authentication instanceof CustomUsernameAuthenticationToken)) {
Object salt = null;
if (this.getSaltSource() != null) {
salt = this.getSaltSource().getSalt(userDetails);
}
if (!getPasswordEncoder().isPasswordValid(userDetails.getPassword(), authentication.getCredentials().toString(), salt)) {
throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), userDetails);
}
}
}
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Assert.isInstanceOf( UsernamePasswordAuthenticationToken.class, authentication, messages .getMessage(
"AbstractUserDetailsAuthenticationProvider.onlySupports", "Only UsernamePasswordAuthenticationToken is supported"));
// Determine username
String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED" : authentication.getName();
boolean cacheWasUsed = true;
UserDetails user = this.getUserCache().getUserFromCache(username);
if (user == null) {
cacheWasUsed = false;
try {
user = retrieveUserCustom(username, (UsernamePasswordAuthenticationToken) authentication);
} catch (UsernameNotFoundException notFound) {
if (hideUserNotFoundExceptions) {
throw new BadCredentialsException( messages .getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
} else {
throw notFound;
}
}
Assert.notNull(user, "retrieveUser returned null - a violation of the interface contract");
}
if (!user.isAccountNonLocked()) {
throw new LockedException(messages.getMessage( "AbstractUserDetailsAuthenticationProvider.locked", "User account is locked"));
}
if (!user.isEnabled()) {
if (authentication instanceof CustomUsernamePasswordAuthenticationToken) {
throw new CustomAuthenticationException("该证书绑定帐号还未启用或者已禁用!", CustomAuthenticationException.CODE_CA, -1);
} else {
throw new DisabledException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.disabled", "User is disabled"));
}
}
if (!user.isAccountNonExpired()) {
throw new AccountExpiredException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.expired", "User account has expired"));
}
// This check must come here, as we don't want to tell users
// about account status unless they presented the correct credentials
try {
additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
} catch (AuthenticationException exception) {
// There was a problem, so try again after checking we're using
// latest data
cacheWasUsed = false;
user = retrieveUserCustom(username, (UsernamePasswordAuthenticationToken) authentication);
additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
}
if (!user.isCredentialsNonExpired()) {
throw new CredentialsExpiredException(messages .getMessage( "AbstractUserDetailsAuthenticationProvider.credentialsExpired", "User credentials have expired"));
}
if (!cacheWasUsed) {
this.getUserCache().putUserInCache(user);
}
Object principalToReturn = user;
if (isForcePrincipalAsString()) {
principalToReturn = user.getUsername();
}
return createSuccessAuthentication(principalToReturn, authentication, user);
}
protected final UserDetails retrieveUserCustom(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
UserDetails loadedUser;
if (authentication instanceof CustomUsernamePasswordAuthenticationToken) {
try {
loadedUser = ((CustomJdbcDaoImpl) this.getUserDetailsService())
.loadUserByCaid(authentication.getName());
} catch (DataAccessException repositoryProblem) {
throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
}
if (loadedUser == null) {
throw new AuthenticationServiceException("AuthenticationDao returned null, which is an interface contract violation");
}
} else {
loadedUser = this.retrieveUser(username, authentication);
}
return loadedUser;
}
}