package com.mzl.flower.config.security.provider; 
 | 
  
 | 
import lombok.extern.slf4j.Slf4j; 
 | 
import org.springframework.beans.factory.InitializingBean; 
 | 
import org.springframework.context.MessageSource; 
 | 
import org.springframework.context.MessageSourceAware; 
 | 
import org.springframework.context.support.MessageSourceAccessor; 
 | 
import org.springframework.security.authentication.*; 
 | 
import org.springframework.security.core.Authentication; 
 | 
import org.springframework.security.core.AuthenticationException; 
 | 
import org.springframework.security.core.SpringSecurityMessageSource; 
 | 
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; 
 | 
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper; 
 | 
import org.springframework.security.core.userdetails.UserCache; 
 | 
import org.springframework.security.core.userdetails.UserDetails; 
 | 
import org.springframework.security.core.userdetails.UserDetailsChecker; 
 | 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 
 | 
import org.springframework.security.core.userdetails.cache.NullUserCache; 
 | 
import org.springframework.util.Assert; 
 | 
  
 | 
@Slf4j 
 | 
public abstract class SelfAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware { 
 | 
  
 | 
    protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor(); 
 | 
    private UserCache userCache = new NullUserCache(); 
 | 
    private boolean forcePrincipalAsString = false; 
 | 
    protected boolean hideUserNotFoundExceptions = true; 
 | 
    private UserDetailsChecker preAuthenticationChecks = new DefaultPreAuthenticationChecks(); 
 | 
    private UserDetailsChecker postAuthenticationChecks = new DefaultPostAuthenticationChecks(); 
 | 
    private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper(); 
 | 
  
 | 
  
 | 
    protected abstract void additionalAuthenticationChecks(UserDetails userDetails, 
 | 
                                                           Authentication authentication) 
 | 
            throws AuthenticationException; 
 | 
     
 | 
    @Override 
 | 
    public void afterPropertiesSet() throws Exception { 
 | 
        Assert.notNull(this.userCache, "A user cache must be set"); 
 | 
        Assert.notNull(this.messages, "A message source must be set"); 
 | 
        doAfterPropertiesSet(); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
 | 
        String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED" : authentication.getName(); 
 | 
  
 | 
        boolean cacheWasUsed = true; 
 | 
        UserDetails user = this.userCache.getUserFromCache(username); 
 | 
  
 | 
        if (user == null) { 
 | 
            cacheWasUsed = false; 
 | 
  
 | 
            try { 
 | 
                user = retrieveUser(username, authentication); 
 | 
            } 
 | 
            catch (UsernameNotFoundException notFound) { 
 | 
                log.debug("User '" + username + "' not found"); 
 | 
  
 | 
                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"); 
 | 
        } 
 | 
  
 | 
        try { 
 | 
            preAuthenticationChecks.check(user); 
 | 
            additionalAuthenticationChecks(user, authentication); 
 | 
        } 
 | 
        catch (AuthenticationException exception) { 
 | 
            if (cacheWasUsed) { 
 | 
                cacheWasUsed = false; 
 | 
                user = retrieveUser(username, authentication); 
 | 
                preAuthenticationChecks.check(user); 
 | 
                additionalAuthenticationChecks(user, authentication); 
 | 
            } 
 | 
            else { 
 | 
                throw exception; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        postAuthenticationChecks.check(user); 
 | 
  
 | 
        if (!cacheWasUsed) { 
 | 
            this.userCache.putUserInCache(user); 
 | 
        } 
 | 
  
 | 
        Object principalToReturn = user; 
 | 
  
 | 
        if (forcePrincipalAsString) { 
 | 
            principalToReturn = user.getUsername(); 
 | 
        } 
 | 
  
 | 
        return createSuccessAuthentication(principalToReturn, authentication, user); 
 | 
    } 
 | 
  
 | 
    protected abstract Authentication createSuccessAuthentication(Object principal, 
 | 
                                                         Authentication authentication, UserDetails user); 
 | 
  
 | 
    protected void doAfterPropertiesSet() throws Exception { 
 | 
    } 
 | 
  
 | 
    public UserCache getUserCache() { 
 | 
        return userCache; 
 | 
    } 
 | 
  
 | 
    public boolean isForcePrincipalAsString() { 
 | 
        return forcePrincipalAsString; 
 | 
    } 
 | 
  
 | 
    public boolean isHideUserNotFoundExceptions() { 
 | 
        return hideUserNotFoundExceptions; 
 | 
    } 
 | 
  
 | 
    protected abstract UserDetails retrieveUser(String username, Authentication authentication) throws AuthenticationException; 
 | 
  
 | 
    public void setForcePrincipalAsString(boolean forcePrincipalAsString) { 
 | 
        this.forcePrincipalAsString = forcePrincipalAsString; 
 | 
    } 
 | 
  
 | 
    public void setHideUserNotFoundExceptions(boolean hideUserNotFoundExceptions) { 
 | 
        this.hideUserNotFoundExceptions = hideUserNotFoundExceptions; 
 | 
    } 
 | 
  
 | 
    public void setMessageSource(MessageSource messageSource) { 
 | 
        this.messages = new MessageSourceAccessor(messageSource); 
 | 
    } 
 | 
  
 | 
    public void setUserCache(UserCache userCache) { 
 | 
        this.userCache = userCache; 
 | 
    } 
 | 
  
 | 
    protected UserDetailsChecker getPreAuthenticationChecks() { 
 | 
        return preAuthenticationChecks; 
 | 
    } 
 | 
  
 | 
    public void setPreAuthenticationChecks(UserDetailsChecker preAuthenticationChecks) { 
 | 
        this.preAuthenticationChecks = preAuthenticationChecks; 
 | 
    } 
 | 
  
 | 
    protected UserDetailsChecker getPostAuthenticationChecks() { 
 | 
        return postAuthenticationChecks; 
 | 
    } 
 | 
  
 | 
    public void setPostAuthenticationChecks(UserDetailsChecker postAuthenticationChecks) { 
 | 
        this.postAuthenticationChecks = postAuthenticationChecks; 
 | 
    } 
 | 
  
 | 
    public void setAuthoritiesMapper(GrantedAuthoritiesMapper authoritiesMapper) { 
 | 
        this.authoritiesMapper = authoritiesMapper; 
 | 
    } 
 | 
  
 | 
    private class DefaultPreAuthenticationChecks implements UserDetailsChecker { 
 | 
        public void check(UserDetails user) { 
 | 
            if (!user.isAccountNonLocked()) { 
 | 
                log.debug("User account is locked"); 
 | 
  
 | 
                throw new LockedException(messages.getMessage( 
 | 
                        "AbstractUserDetailsAuthenticationProvider.locked", 
 | 
                        "User account is locked")); 
 | 
            } 
 | 
  
 | 
            if (!user.isEnabled()) { 
 | 
                log.debug("User account is disabled"); 
 | 
  
 | 
                throw new DisabledException(messages.getMessage( 
 | 
                        "AbstractUserDetailsAuthenticationProvider.disabled", 
 | 
                        "User is disabled")); 
 | 
            } 
 | 
  
 | 
            if (!user.isAccountNonExpired()) { 
 | 
                log.debug("User account is expired"); 
 | 
  
 | 
                throw new AccountExpiredException(messages.getMessage( 
 | 
                        "AbstractUserDetailsAuthenticationProvider.expired", 
 | 
                        "User account has expired")); 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private class DefaultPostAuthenticationChecks implements UserDetailsChecker { 
 | 
        public void check(UserDetails user) { 
 | 
            if (!user.isCredentialsNonExpired()) { 
 | 
                log.debug("User account credentials have expired"); 
 | 
  
 | 
                throw new CredentialsExpiredException(messages.getMessage( 
 | 
                        "AbstractUserDetailsAuthenticationProvider.credentialsExpired", 
 | 
                        "User credentials have expired")); 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
} 
 |