📑本篇内容:如何理解学习SpringSecurity的常用拦截器——举例进行学习
📘 文章专栏:前后端分离项目(Vue + SpringBoot)
🎬最近更新:2022年2月5日 Nginx 入门到实战案例 配置反向代理、负载均衡、动静分离以及对Nginx高可用的服务器集群
🙊个人简介:一只二本院校在读的大三程序猿,本着注重基础,打卡算法,分享技术作为个人的经验总结性的博文博主,虽然可能有时会犯懒,但是还是会坚持下去的,如果你很喜欢博文的话,建议看下面一行~(疯狂暗示QwQ)
🌇点赞 👍 收藏 ?留言 📝 一键三连 关爱程序猿,从你我做起
📑如何理解原理并学习SpringSecurity的常用拦截器——举例进行学习
🚀1、SpringSecurity官方文档进行学习
SpringSecurity官方参阅文献
Hello Spring Security :: Spring Security
?SpringSecurity中的SpringBootAutoConfiguration?
官方文档:
-
SpringSecurity默认的自动装配配置。创建了一个叫做springSecurityFilterChain 的 Servlet Filter 过滤器链,将这个组件注入到Spring容器当中,他负责针对于应用程序的路径地址 、进行验证提交的用户名和密码 、如果失败则重新定向到登录表单 等操作。 -
创建了一个叫做 UserDetailsService 的用户细节服务的组件bean,该bean的username为user ,并且随机生成了一串密码以日志形式展示在控制台 中。 -
针对于所有的请求,向Servlet容器中注册了一个名为springSecurityFilterChain 的过滤器Bean。
🚀2、常用到的过滤器链解析——举例学习
?UsernamePasswordAuthenticationFilter?
学习参考地址
Spring Security UsernamePasswordAuthenticationFilter
- 当我们的用户名和密码进行提交之后,过滤器链中的
UsernamePasswordAuthenticationFilter 就会开始对用户名和密码进行身份认证,UsernamePasswordAuthenticationFilter 类继承了 AbstractAuthenticationProcessingFilter 这个抽象类。
AbstractAuthenticationProcessingFilter 是干啥的有啥用?
学习参考地址:Spring Security AbstractAuthenticationProcessingFilter
简单来说:这个抽象类是用于验证用户凭据的基本过滤器的抽象类。在验证凭据之前会通过使用AuthenticationEntryPoint类来请求凭据。
AuthenticationEntryPoint 又是干啥的呢?
学习参考地址:Spring Security AuthenticationEntryPoint
通过对源码的查看:
public interface AuthenticationEntryPoint {
void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException;
}
这个是个接口 其具体的实现类如图所示:
简单来说:我们可以理解这个接口是用于实现接受客户端发来的凭据,然后根据凭证是否认证成功做出Http响应
然后我们回到我们的 AbstractAuthenticationProcessingFilter 的学习。
当我们利用 AuthenticationEntryPoint 请求凭据之后,AbstractAuthenticationProcessingFilter 可以验证提交给它的任何身份验证请求。
如图所示:
-
当用户提交提交了凭据时,AbstractAuthenticationProcessingFilter 就会从 HttpServletRequest 中创建一个进行身份验证的 由 Authentication 实现的一个身份验证类型进行验证。 而不同的身份验证类型 是根据继承了 AbstractAuthenticationProcessingFilter 抽象类的子类来定义的。例如:UsernamePasswordAuthenticationFilter 会根据 HttpServletRequest 中提交的用户名和密码创建一个继承了 AbstractAuthenticationToken抽象类同时实现了Authentication这个接口的UsernamePasswordAuthenticationToken类的身份认证类型来进行认证。 -
之后呢 ,刚才创建好实现了Authentication 接口的 UsernamePasswordAuthenticationToken 身份认证类型就会传入到 AuthenticationManager 进行身份验证。 -
如果认证失败:
-
会将SecurityContextHolder中的数据清空。
什么是SecurityContextHolder呢?
参考文档: Spring Security SecurityContextHolder
简单来说就是:存放了Principal(用户名)、Credentials(密码凭据)、Authorities(权限)三个数据的上下文
-
接口RememberMeServices 下的loginFail() 方法会被执行,如果没有配置RememberMeServices 服务此时就零配置。 -
接口AuthenticationFailureHandler 下的 onAuthenticationFailure() 方法也会被执行。 -
如果认证成功:
SessionAuthenticationStrategy 中的onAuthentication() 方法会被执行,同时收到了登录成功的Session信息。Authentication 认证类型信息也会设置在 SecurityContextHolder 中,然后,SecurityContextPersistenceFilter 这个过滤器会将 SecurityContext 保存在 HttpSession 中。- 接口
RememberMeServices 下的loginSuccess() 方法会被执行,如果没有配置RememberMeServices 服务此时就零配置。 - 接口
ApplicationEventPublisher 下的publishEvent() 方法会发布一个InteractiveAuthenticationSuccessEvent 的事件。 - 接口
AuthenticationSuccessHandler 下的onAuthenticationSuccess() 方法会被执行。
现在我们了解了AbstractAuthenticationProcessingFilter这个抽象过滤器链,那咱们就可以来学习这个常用的过滤器链UsernamePasswordAuthenticationFilter了
-
当用户提交他们的用户名和密码时,UsernamePasswordAuthenticationFilter 创建一个UsernamePasswordAuthenticationToken 他是实现了Authentication 接口的一个身份验证类型。通过源码得知: public UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
super((Collection)null);
this.principal = principal;
this.credentials = credentials;
this.setAuthenticated(false);
}
实际上就是将HttpServletRequest中获取的username赋给了principal ,password赋给了credentials,同时设置了是否验证过了。 -
随后UsernamePasswordAuthenticationToken 身份认证类型就会传入到 AuthenticationManager 进行身份验证。 -
如果验证失败
-
会将SecurityContextHolder中的数据清空。 -
接口RememberMeServices 下的loginFail() 方法会被执行,如果没有配置RememberMeServices 服务此时就零配置。 -
接口AuthenticationFailureHandler 下的 onAuthenticationFailure() 方法也会被执行。 -
如果验证成功
-
SessionAuthenticationStrategy 中的onAuthentication() 方法会被执行,同时收到了登录成功的Session信息。 -
Authentication 认证类型信息也会设置在 SecurityContextHolder 中,然后,SecurityContextPersistenceFilter 这个过滤器会将 SecurityContext 保存在 HttpSession 中。 -
接口RememberMeServices 下的loginSuccess() 方法会被执行,如果没有配置RememberMeServices 服务此时就零配置。 -
接口ApplicationEventPublisher 下的publishEvent() 方法会发布一个InteractiveAuthenticationSuccessEvent 的事件。 -
AuthenticationSuccessHandler 被调用。 通常交给SimpleUrlAuthenticationSuccessHandler 处理器来进行处理,当我们重定向到登录页面时,它会重定向到ExceptionTranslationFilter 保存的请求地址。
🙊3、总结
以上是今天小付在整合SpringBoot与SpringSecurity时再次学习SpringSecurity的官方参考文献做出的记录,SpringSecurity中的第一个常用拦截器 UsernamePasswordAuthenticationFilter 的使用及其工作原理,从其继承的抽象类AbstractAuthenticationProcessingFilter 进行入手,然后通过对其分析 将身份认证时用到的UsernamePasswordAuthenticationToken 认证类型也进行了分析**,如何快速掌握其原理**,也再次牢记,就先写这么多了,好久没写技术文了,今天补一篇,接着肝项目去了~
|