一.springsecurity的认证流程
1.1 常用过滤器
SpringSecurity 采用的是责任链的设计模式,它有一条很长的过滤器链。现在对这条过滤器链的 15 个过滤器进行说明:
WebAsyncManagerIntegrationFilter | 将 Security 上下文与 Spring Web 中用于 处理异步请求映射的 WebAsyncManager 进行集成。 |
SecurityContextPersistenceFilter | 在每次请求处理之前将该请求相关的安全上 下文信息加载到 SecurityContextHolder 中,然后在该次请求处理完成之后,将 SecurityContextHolder 中关于这次请求的信息存储到一个“仓储”中,然后将 SecurityContextHolder 中的信息清除,例如在 Session 中维护一个用户的安全信 息就是这个过滤器处理的。 |
HeaderWriterFilter | 用于将头信息加入响应中 |
CsrfFilter | 用于处理跨站请求伪造 |
LogoutFilter | 用于处理退出登录 |
UsernamePasswordAuthenticationFilter | 用于处理基于表单的登录请求,从表单中 获取用户名和密码。默认情况下处理来自 /login 的请求。从表单中获取用户名和密码 时,默认使用的表单 name 值为 username 和 password,这两个值可以通过设置这个 过滤器的 usernameParameter 和 passwordParameter 两个参数的值进行修改。 |
DefaultLoginPageGeneratingFilter | 如果没有配置登录页面,那系统初始化时就会 配置这个过滤器,并且用于在需要进行登录时生成一个登录表单页面。 |
BasicAuthenticationFilter | 检测和处理 http basic 认证 |
RequestCacheAwareFilter | 用来处理请求的缓存 |
SecurityContextHolderAwareRequestFilter | 主要是包装请求对象 request |
AnonymousAuthenticationFilter | 检测 SecurityContextHolder 中是否存在 Authentication 对象,如果不存在为其提供一个匿名 Authentication |
SessionManagementFilter | 管理 session 的过滤器 |
ExceptionTranslationFilter | 处理 AccessDeniedException 和 AuthenticationException 异常。 |
FilterSecurityInterceptor | 可以看做过滤器链的出口 |
RememberMeAuthenticationFilter | 当用户没有登录而直接访问资源时, 从 cookie 里找出用户的信息, 如果 Spring Security 能够识别出用户提供的 remember me cookie, 用户将不必填写用户名和密码, 而是直接登录进入系统,该过滤器默认不开启。 |
1.2 认证的宏观流程
Spring Security 采取过滤链实现认证与授权,只有当前过滤器通过,才能进入下一个过滤器,绿色部分是认证过滤器,需要我们自己配置,可以配置多个认证过滤器。认证过滤器可以使用 Spring Security 提供的认证过滤器,也可以自定义过滤器(例如:短信验证)。认证过滤器要在 configure(HttpSecurity http)方法中配置,没有配置不生效。
1.UsernamePasswordAuthenticationFilter 过滤器:该过滤器会拦截前端提交的 POST 方式的登录表单请求,并进行身份认证。
2.ExceptionTranslationFilter过滤器:该过滤器不需要我们配置,对于前端提交的请求会直接放行,捕获后续抛出的异常并进行处理(例如:权限访问限制)。
3.FilterSecurityInterceptor 过滤器:该过滤器是过滤器链的最后一个过滤器,根据资源权限配置来判断当前请求是否有权限访问对应的资源。如果访问受限会抛出相关异常,并由 ExceptionTranslationFilter 过滤器进行捕获和处理。
从上图中可以看到Spring Security第一个拦截器是SecurityContextPersistenceFilter,它主要存放用户的认证信息。然后进入第二个拦截器UsernamePasswordAuthenticationFilter,它主要用来拦截Spring Security拦截用户密码表单登录认证使用(默认,当发现请求是Post,请求地址是/login,且参数包含了username/password时,就进入了认证环节)。
1.3 代码详情分析
认证流程是在 UsernamePasswordAuthenticationFilter 过滤器中处理的,具体流程如下所示:
1.4 代码详情
后续补充,见sgg的pdf
二.springsecurity的授权流程
2.1 授权流程
授权主要涉及两个过滤器:ExceptionTranslationFilter 过滤器和 FilterSecurityInterceptor 过滤器。
![](https://i-blog.csdnimg.cn/blog_migrate/3222ecf3b1826f908cfc811962a3714e.png)
2.1.2 FilterSecurityInterceptor 过滤器
![](https://i-blog.csdnimg.cn/blog_migrate/a8b5cc29aed66ba388e0a1d4287d9ca7.png)
三 认证信息的共享存储
3.1 流程图
流程:
在 UsernamePasswordAuthenticationFilter 过滤器认证成功之 后,会在认证成功的处理方法中将已认证的用户信息对象 Authentication 封装进 SecurityContext,并存入 SecurityContextHolder之后,响应会通过 SecurityContextPersistenceFilter 过滤器,该过滤器的位置在所有过滤器的最前面。
认证成功的响应通过 SecurityContextPersistenceFilter 过滤器时,会从 SecurityContextHolder 中取出封装了已认证用户信息对象 Authentication 的SecurityContext,放进 Session 中。当请求再次到来时,请求首先经过该过滤器,该过滤器会判断当前请求的 Session 是否存有 SecurityContext对象,如果有则将该对象取出再次放入 SecurityContextHolder 中,之后该请求所在的线程获得认证用户信息,后续的资源访问不需要进行身份认证;当响应再次返回时,该过滤器同样从 SecurityContextHolder 取出SecurityContext 对象,放入 Session 中。