在**Spring**中, **Shiro**和**spring-security**是比较常用的安全框架解决方案, **shiro**在中小型项目中使用通常来说既简单, 也能达到常规的需求, 如果项目较为复杂, 建议**spring-security**
**Spring Security OAuth2.0**已经停止维护, **oauth2-authorization-server**是目前官方推荐的安全框架方案, 所以值得学习
本文以密码登陆认证流程为基础, 简要剖析登陆认证执行流程
**软件版本 **
spring-security-oauth2-authorization-server 0.4.2
spring-boot 2.7.11 (也是spring-cloud-alibaba-2021.0.5.0 对应的boot版本)
不管是 Shiro还是本文oauth2-authorization-server, 及大部分安全框架都是基于Filter拦截请求实现的, 所以我们直接找到对应的过滤器
我们以密码登陆为例http://localhost:8080/oauth2/token, 关注红色部分参数即可
该请求会被框架的
org.springframework.security.oauth2.server.authorization.web.OAuth2ClientAuthenticationFilter
过滤器拦截到, 代码如下
在图标记1处我们可以看到, 框架默认填充了4个converter, 来接收我们的请求参数, 在我们的登陆请求中我们的请求会在图片标记2处被第二个converter所处理,就是这个ClientSecretBasicAuthenticationConverter
为什么是第二个converter, 我们可以结合登陆请求参数看**ClientSecretBasicAuthenticationConverter**源码,我们发现有这一段代码
大意就是如果请求头包含 Authorization 就执行下面逻辑, 刚好我们的请求是包含了这个header,所以会使用这个converter生成一个未认证的认证对象
回到OAuth2ClientAuthenticationFilter类的标记3处, 经过converter生成的认证对象会被authenticationManager调用authenticate进行认证, **我们看authenticationManager的实现类ProviderManager中的authenticate方法**
我们可以非常清楚的看到, ProviderManager会尝试使用所有的provider进行处理, 我们也可以看到 provider的实现类也是非常多的
最终采用那个provider取决于provider是否能支持前面converter**生成的认证对象. **注意可出现多个provider支持同一种类型的认证对象"情况
** ** 还是以我们的请求参数被ClientSecretBasicAuthenticationConverter转化生成的未认证的认证对象OAuth2ClientAuthenticationToken 为例, 这个认证对象会在ClientSecretAuthenticationProvider进行认证处理,
可以看到ClientSecretAuthenticationProvider是支持OAuth2ClientAuthenticationToken 类型的认证对象的, 因此会使用ClientSecretAuthenticationProvider提供的authenticate认证方法 在ClientSecretAuthenticationProvider的认证方法内, 我们可以看到完整的认证流程
其中registeredClientRepository是我们需要关注的, 这个类通常我们需要自定义重写, 方法中它会尝试通过clientId来查找认证对象的实体数据, 我们自定义重写后, 我们就可以关联自己的数据库查询, 如果认证成功, 方法会生成一个认证成功****的认证对象
** 认证成功后会调用 图2中的标记4**处
this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, authenticationResult);
方法中内容如下
创建一个SecurityContext上下文, 把已认证的认证对象放到这个上下文中, 供后续的使用
我们知道整个认证流程是包含客户端认证+用户认证, 上述认证流程是在进行客户端数据认证, 后续还包括用户认证, 用户认证流程大体类似, OAuth2TokenEndpointFilter 会接收通过上文 OAuth2ClientAuthenticationFilter 客户端认证的请求, 流程都分为3部分, 第一通过converter转化请求数据成未认证的认证对象, 第二步authenticationManager去匹配合适的provider进行具体的认证流程生成已认证的认证对象, 第三步就是通过AuthenticationSuccessHandler来处理最后的结果, 如返回认证登陆生成的token
总结
oauth2-authorization-server已做了很多封装处理, 在使用过程中, 我们主要关注这几个部分
第一, 各种Converter
或者我们自定义Converter, 如果自定义Converter通常需要自定义认证对象, 自定义Converter和认证对象都可以参考框架提供的, 如我们分析的ClientSecretBasicAuthenticationConverter和对应的认证对象OAuth2ClientAuthenticationToken
第二, 各种Provider
ProviderManager在认证时会遍历全部Provider, 匹配合适的provider, 如自定义了provider需要重写supports来匹配provider能处理的认证对象, 并重写authenticate进行自定义认证流程
第三, 定义好AuthenticationSuccessHandler, 及时处理认证成功的数据, 响应给请求者AuthenticationSuccessHandler与认证流程采用的是订阅监听模式, 不及时处理可出现后续无效验证
后续, 本文只讲解oauth2-authorization-server认证流程, 授权功能暂未分析, 后续继续
版权归原作者 qq_26452719 所有, 如有侵权,请联系我们删除。