spring security certification

1.spring security mainly in order to make authentication and authorization, through a series of filter chain;

Certification process is as follows:

 

 

The default security authentication process do filters for UsernamePasswordAuthenticationFilter , the class inherits AbstractAuthenticationProcessingFilter, first class execution AbstractAuthenticationProcessingFilter

dofilter methods, such as source code dofiter:

 void the doFilter public (the ServletRequest REQ, the ServletResponse RES, the FilterChain catena alberghiera) throws IOException, {ServletException
        the HttpServletRequest Request = (the HttpServletRequest) REQ;
        the HttpServletResponse Response = (the HttpServletResponse) RES;
        . //. 1 determines whether the current filter can process the current request, not if the processing to the next filter
        IF {(this.requiresAuthentication (Request, Response)!)
            the chain.doFilter (Request, Response);
        } {the else
            IF (this.logger.isDebugEnabled ()) {
                this.logger.debug ( "IS to the Request Process authentication");
            }

            the authentication authResult;
            the try {
                / ** subclass of abstract methods from the real UsernamePasswordAuthenticationFilter
                AttemptAuthentication now, mainly acquire the authentication information, according to their class inheritance UsernamePasswordAuthenticationFilter actual needs, a method override attemptAuthentication
                ** /
                authResult = this.attemptAuthentication (Request, Response);
                IF (authResult == null) {
                    return;
                }
                // certification after successful treatment of some methods associated with the session
                this.sessionStrategy.onAuthentication (authResult, Request, Response);
            } the catch (InternalAuthenticationServiceException var8) {
                this.logger.error (, "An Internal error occurred to the authenticate the while Trying the User." var8);
                some operations after // authentication failure
                this.unsuccessfulAuthentication (Request, Response, var8);
                return;
            } the catch (var9 of AuthenticationException) {
                this.unsuccessfulAuthentication (Request, Response, var9);
                return;
            }

            IF (this.continueChainBeforeSuccessfulAuthentication) {
                the chain.doFilter (Request, Response);
            }
            // callback after successful authentication methods related mainly to the current certification into the SecurityContextHolder
            this.successfulAuthentication (Request, the Response, catena alberghiera, authResult);
        }
    }

AbstractAuthenticationProcessingFilter class dofilter mainly performed UsernamePasswordAuthenticationFilter class attemptAuthentication method source code for:

public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
    private String usernameParameter = "username";
    private String passwordParameter = "password";
    private boolean postOnly = true;

    public UsernamePasswordAuthenticationFilter() {
        super(new AntPathRequestMatcher("/login", "POST"));
    }

    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (this.postOnly && !request.getMethod().equals("POST")) {
            new new AuthenticationServiceException the throw ( "the Authentication Method Not Supported:" + request.getMethod ());
        } the else {
            // Get the value of the username request from the request
            String username = this.obtainUsername (request);
            // password acquisition request from the request value
            String password = this.obtainPassword (Request);
            IF (username == null) {
                username = "";
            }

            IF (password == null) {
                password = ";"
            }

            username = username.trim ();
            // UsernamePasswordAuthenticationToken building object by a user name and password, role information (username, password, session, etc.) requested by the user of the package to the object
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
            this.setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
        }
    }

 

 

 It should be noted that it is important, Super ((Collection) null); Collection represents the permissions list, which passed in a null into it because there is no beginning and authentication, so the user does not have any authority at this time, and set the authentication information is not setAuthenticated (false) ;

Back to UsernamePassworkAuthenticationFilter attemptAuthentication () method, you can see the last method called getAuthenticationManager () method, and then enter the implementation class ProviderManager AuthenticationManager interface.

 Supplementary: AuthenticationManager does not contain the user name and password authentication, but to manage AuthenticationProvider, all validation rules are written in AuthenticationProvider in;

 

 

 然后执行ProciderManager中authenticate方法,该方法中主要执行AuthenticationProvider类中authenticate方法,用户的信息权限的验证就在该类中校验,可根据实际需要实现AuthenticationProvider接口,重写authenticate方法

 

 

进入 ProviderManager 类后会调用 authenticate(Authentication authentication) 方法,它通过 AuthenticationProvider 实现类获取用户的登录的方式,然后会有一个 while 迭代器模式的循环遍历,检查它是否支持这种登录方式,具体的登录方式有表单登录,qq登录,微信登录等。如果最终都不支持会抛出相应的异常信息,如果支持则会进入AuthenticationProvider 接口的抽象实现类 AbstractUserDetailsAuthenticationProvider 中。

AbstractUserDetailsAuthenticationProvider 类后会调用 authenticate(Authentication authentication) 方法源码如下:

进入 AbstractUserDetailsAuthenticationProvider 类后会调用 authenticate(Authentication authentication) 方法对用户的身份进行校验,首先是判断用户是否为空,这个 user 是 UserDetail 的对象,如果为空,表示还没有认证,就需要调用 retrieveUser 方法去获取用户的信息,这个方法是抽象类 AbstractUserDetailsAuthenticationProvider 的扩展类DaoAuthenticationProvider 的一个方法。

 

 

DaoAuthenticationProvider中retrieveUser源码如下:

在该扩展类中,retrieveUser调用UserDetailsService接口实现类中的loadUserByUsername方法去获取用户信息,所以本地可以实现UserDetailsService接口,在这个实现类中,编写自己的逻辑

Guess you like

Origin www.cnblogs.com/zpp1234/p/12170579.html