美文网首页
SpringSecurity 认证流程

SpringSecurity 认证流程

作者: DOB_8199 | 来源:发表于2021-12-20 19:00 被阅读0次

    认证流程


    认证流程是在 UsernamePasswordAuthenticationFilter 过滤器中处理的,具体流程如下所示:


    UsernamePasswordAuthenticationFilter 源码


    查看源码我们首先从过滤器的 doFilter() 方法看起,它实现在其抽象父类AbstractAuthenticationProcessingFilter 中,查看相关源码:

    首先在子类UsernamePasswordAuthenticationFilter的空参构造器中调用了父类的构造器:将POST信息传给了父类的属性

    调用了父类的构造器 将POST信息传给了父类的属性

    在父类的dofilter中调用了requiresAuthentication判断是否为post请求:

    1. 判断该请求是否为POST方式的登陆表单提交请求,如果不是则直接放行,进入下一个过滤器

    2. 放行后,调用了父类的接口attemptAuthentication,在没重写前调用的是子类UsernamePasswordAuthenticationFilter的attemptAuthentication()方法(也就是我们会重写的方法,为了获取表单提交过来的数据,并将用户的信息封装到Authentication中去)

    在UsernamePasswordAuthenticationFilter子类中它是这样的:

    判断是否为post提交,获取表单提交过来的用户名和密码封装到UsernamePasswordAuthenticationToken中去,表示为一个未认证的对象UsernamePasswordAuthenticationToken(附录一介绍)。并将请求的一些属性信息例如session等,封装到该UsernamePasswordAuthenticationToken对象中。调用ProvideManager中的authenticate方法进行身份验证(调用的是自己编写的UserDetailsService进行认证)(附录二介绍)

    我们重写后是这样的:

    3. Session策略处理,如果配置了用户Session最大并发数,就是在此处进行判断并处理

    4.  默认的continueChainBeforeSuccessfulAuthentication为false,所以认证成功后不进入下一个过滤器

    5. 认证成功调用successfulAuthentication,认证失败在catch中处理unsuccessfulAuthentication(),这两个方法也是我们重写过的。(重写前代码见附录三)

    重写后为:

    附录一 UsernamePasswordAuthenticationToken


    创建的 UsernamePasswordAuthenticationToken 是Authentication 接口的实现类,该类有两个构造器,一个用于封装前端请求传入的未认证的用户信息,一个用于封装认证成功后的用户信息:

    而它的父类AbstractAuthenticationToken实现了Authentication接口

    Authentication 接口的实现类用于存储用户认证信息,查看该接口具体定义:


    附录二:ProviderManager 源码


    return this.getAuthenticationManager().authenticate(authRequest);

    首先调用到UsernamePasswordAuthenticationFilter的父类AbstractAuthenticationProcessingFilter的方法getAuthenticationManager()获取到在AbstractAuthenticationProcessingFilter中的AuthenticationManager的对象authenticationManager,通过authenticationManager调用authenticate()方法。

    authenticate()是AuthenticationManager接口的一个方法,实现类如下,但这里调用的是ProviderManager中的方法

    上述过程中,UsernamePasswordAuthenticationFilter 过滤器的attemptAuthentication() 将未认证的 Authentication 对象传入ProviderManager 类的 authenticate() 方法进行身份认证。

    ProviderManager 是 AuthenticationManager 接口的实现类,该接口是认证相关的核心接口,也是认证的入口。在实际开发中,我们可能有多种不同的认证方式,例如:用户名+密码、邮箱+密码、手机号+验证码等,而这些认证方式的入口始终只有一个,那就是AuthenticationManager。在该接口的常用实现类 ProviderManager 内部会维护一个List<AuthenticationProvider>列表,存放多种认证方式,实际上这是委托者模式(Delegate)的应用。每种认证方式对应着一个 AuthenticationProvider,AuthenticationManager 根据认证方式的不同(根据传入的 Authentication 类型判断)委托对应的 AuthenticationProvider 进行用户认证。

    上述认证成功之后的(6)过程,调用 CredentialsContainer 接口定义的eraseCredentials() 方法去除敏感信息。查看UsernamePasswordAuthenticationToken 实现的 eraseCredentials() 方法,该方法实现在其父类中:


    附录三:认证成功/失败处理


    上述过程就是认证流程的最核心部分,接下来重新回到UsernamePasswordAuthenticationFilter 过滤器的 doFilter() 方法,查看认证成功/失败的处理:

    查看 successfulAuthentication()和unsuccessfulAuthentication()方法源码

    相关文章

      网友评论

          本文标题:SpringSecurity 认证流程

          本文链接:https://www.haomeiwen.com/subject/fjuofrtx.html