Spring Security认证流程分

1.认证流程分析

  Spring Security中默认的一套登录流程是非常完善并且严谨的。但是项目需求非常多样化, 很多时候,我们可能还需要对Spring Secinity登录流程进行定制,定制的前提是开发者先深刻理解Spring Security登录流程,然后在此基础之上,完成对登录流程的定制。本文将从头梳理 Spring Security登录流程,并通过几个常见的登录定制案例,深刻地理解Spring Security登录流程。

  本章涉及的主要知识点有:

1.1登录流程分析

  要搞清楚Spring Security认证流程,我们得先认识与之相关的三个基本组件(Authentication 对象在前面文章种己经做过介绍,这里不再赘述):AuthenticationManager、ProviderManager以及AuthenticationProvider,同时还要去了解接入认证功能的过滤器 AbstractAuthenticationProcessingFilter,这四个类搞明白了,基本上认证流程也就清楚了,下面我们逐个分析一下。

1.1.1 AuthenticationManager

  从名称上可以看出,AuthenticationManager是一个认证管理器,它定义了 Spring Security 过滤器要如何执行认证操作。AuthenticationManager在认证成功后,会返回一个Authentication对象,这个Authentication对象会被设置到SecurityContextHolder中。如果开发者不想用Spring Security提供的一套认证机制,那么也可以自定义认证流程,认证成功后,手动将Authentication 存入 SecurityContextHolder 中。

public interface AuthenticationManager {    Authentication authenticate(Authentication var1) throws AuthenticationException;}

  从 AuthenticationManager 的源码中可以看到,AuthenticationManager 对传入的 Authentication对象进行身份认证,此时传入的Authentication参数只有用户名/密码等简单的属性,如果认证成功,返回的Authentication的属性会得到完全填充,包括用户所具备的角色信息。AuthenticationManager是一个接口,它有着诸多的实现类,开发者也可以自定义 AuthenticationManager的实现类,不过在实际应用中,我们使用最多的是ProviderManager,在 Spring S ecurity 框架中,默认也是使用 ProviderManager。

1.1.2 AuthenticationProvider

  Spring Security支持多种不同的认证方式,不同的认证方式对应不同的身份 类型,AuthenticationProvider就是针对不同的身份类型执行具体的身份认证。例如,常见的 DaoAuthenticationProvider 用来支持用户名/密码登录认证,RememberMeAuthenticationProvider 用来支持“记住我”的认证。

public interface AuthenticationProvider {    Authentication authenticate(Authentication var1) throws AuthenticationException;    boolean supports(Class<?> var1);}

  当使用用户名/密码的方式登录时,对应的AuthenticationProvider实现类是 DaoAuthenticationProvider , 而 DaoAuthenticationProvider 继承自 AbstractUserDetailsAuthenticationProvider并且没有重写authenticate方法,所以具体的认证逻辑在AbstractUserDetailsAuthenticationProvider 的 authenticate 方法中。我们就从 AbstractUserDetailsAuthenticationProvider开始看起:

查看代码

  这就是 AbstractUserDetailsAuthenticationProvider类的工作流程,有几个抽象方法是在 DaoAuthenticationProvider 中实现的,我们再来看一下 DaoAuthenticationProvider中的定义:

查看代码

  在密码学中,旁道攻击(Side-channel attack )又称侧信道攻击、边信道攻击。这种攻击方式不是暴力破解或者是研究加密算法的弱点。它是基于从密码系统的物理实现中获取信息, 比如时间、功率消耗、电磁泄漏等,这些信息可被利用于对系统的进一步破解。

1.1.3 ProviderManager

  ProviderManager是AuthenticationManager的一个重要实现类,正在开始学习之前,我们先通过一幅图来了解一下ProviderManager和AuthenticationProvider之间的关系,如图3-1所示。

图 3-1

  在Spring Security中,由于系统可能同时支持多种不同的认证方式,例如同时支持用户名 /密码认证、RememberMe认证、手机号码动态认证等,而不同的认证方式对应了不同的 AuthenticationProvider,所以一个完整的认证流程可能由多个AuthenticationProvider来提供。

  多个AuthenticationProvider将组成一个列表,这个列表将由ProviderManager代理。换句话说,在 ProviderManager 中存在一个 AuthenticationProvider 列表,在 ProviderManager 中遍历列表中的每一个AuthenticationProvider去执行身份认证,最终得到认证结果。

  ProviderManager 本身也可以再配置一个 AuthenticationManager 作为 parent,这样当 ProviderManager认证失败之后,就可以进入到parent中再次进行认证。理论上来说, ProviderManager的parent可以是任意类型的 AuthenticationManager,但是通常都是由 ProviderManager 来扮演 parent 的角色,也就是 ProviderManager 是 ProviderManager 的 parent。

  ProviderManager本身也可以有多个,多个ProviderManager共用同一个parent,当存在多个过滤器链的时候非常有用。当存在多个过滤器链时,不同的路径可能对应不同的认证方式, 但是不同路径可能又会同时存在一些共有的认证方式,这些共有的认证方式可以在parent中统 一处理。

  根据上面的介绍,图 3-2是ProviderManager和AuthenticationProvider关系图。

图 3-2

  我们重点看一下ProviderManager中的authenticate方法:

查看代码

这段源码的逻辑还是非常清晰的,我们分析一下:

  这就是ProviderManagerauthenticate方法的身份认证逻辑,其他方法的源码要相对简单很多,在这里就不一一解释了,

  现在,大家已经熟悉了 AuthenticationAuthenticationManagerAuthenticationProvider 以 及ProviderManager的工作原理了,接下来的问题就是这些组件如何跟登录关联起来?这就涉及一个重要的过滤器----------------------- AbstractAuthenticationProcessingFilter

1.1.4 AbstractAuthenticationProcessingFilter

  作为 Spring Security 过滤器链中的一环,AbstractAuthenticationProcessingFilter可以用来处理任何提交给它的身份认证,图3-3描述了 AbstractAuthenticationProcessingFilter的工作流程:

图 3-3

  图中显示的流程是一个通用的架构。

  AbstractAuthenticationProcessingFilter作为一个抽象类,如果使用用户名/密码的方式登录, 那么它对应的实现类是 UsernamePasswordAuthenticationFilter;构造出来的 Authentication 对象则是 UsernamePasswordAuthenticationToken。至于 AuthenticationManager,前面已经说过,一 般情况下它的实现类就是ProviderManager,这里在ProviderManager中进行认证,认证成功就会进入认证成功的回调,否则进入认证失败的回调。因此,我们可以对上面的流程图再做进一 步细化,如图3-4所示。

图 3-4

  前面第2章中所涉及的认证流程基本上就是这样,我们来大致梳理一下:

  这是认证的一个大致流程。接下来我们结合 AbstractAuthenticationProcessingFilterUsernamePasswordAuthenticationFilter的源码来看一下。

  先来看 AbstractAuthenticationProcessingFilter源码(部分核心代码):

查看代码

  这就是 AbstractAuthenticationProcessingFilter大致上所做的事情,还有一个抽象方法 attemptAuthentication 是在它的继承类 UsernamePasswordAuthenticationFilter中实现的,接下来我们来看—下UsernamePasswordAuthenticationFilter类:

查看代码

  以上就是整个认证流程。

  搞懂了认证流程,那么接下来如果想要自定义一些认证方式,就会非常容易了,比如定义多个数据源、添加登录校验码等。下面,我们将通过两个案例,来活学活用上面所讲的认证流程。

展开阅读全文

页面更新:2024-04-30

标签:流程   过滤器   异常   用户名   对象   密码   事件   方式   方法   用户

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top