一、OAuth2LoginAuthenticationFilter
当gitee收到OAuth2授权请求后,会向浏览器发出302重定向到redirect_uri的响应。由于默认情况下回调的路径满足/login/oauth2/code/*,该路径会被OAuth2LoginAuthenticationFilter登录认证过滤器拦截处理。
二、OAuth2LoginAuthenticationFilter的结构
1、 DEFAULT_FILTER_PROCESSES_URI = “/login/oauth2/code/*”;
默认拦截路径
2、 ClientRegistrationRepository
客户端信息
3、OAuth2AuthorizedClientRepository ;
OAuth2 授权客户端存储库
4、AuthorizationRequestRepository authorizationRequestRepository
从http中操作授权的OAuth2 客户端
5、 Converter<OAuth2LoginAuthenticationToken, OAuth2AuthenticationToken> authenticationResultConverter
token转换器
三、OAuth2登录认证逻辑
OAuth2LoginAuthenticationFilter的核心都在
方法中。主要执行了以下逻辑:
- 校验逻辑
- 校验是否是授权请求的响应。
- 校验当前授权请求的是否真实存在,防止伪造。
- 校验当前授权请求的OAuth2客户端是否合规。
- 组装OAuth2LoginAuthenticationToken并交给OAuth2LoginAuthenticationProvider处理认证
- 认证过的OAuth2LoginAuthenticationToken通过authenticationResultConverter函数转换为OAuth2AuthenticationToken
- 初始化已认证OAuth2客户端对象OAuth2AuthorizedClient并持久化
- 将步骤③生成的OAuth2AuthenticationToken返回
四、OAuth2LoginAuthenticationProvider
1、springsecurity的认证体系
2 、AuthenticationProvider
spring中默认支持17中的认证方式
3、OAuth2LoginAuthenticationToken对应的AuthenticationProvider
OAuth2LoginAuthenticationProvider,
用于普通OAuth2登录认证。OidcAuthorizationCodeAuthenticationProvider
,用于OIDC认证。
4、OAuth2LoginAuthenticationProvider
OAuth2LoginAuthenticationProvider负责使用授权服务器的令牌端点(token-uri)对授权代码凭证进行身份验证,如果认证有效,则将其交换为访问令牌凭证OAuth2AccessToken。
它还将使用OAuth2UserService从用户信息端点(user-info-uri)获取最终用户(资源所有者)的用户信息,用户信息以OAuth2User的形式创建一个Principal 。然后将OAuth2User关联到OAuth2LoginAuthenticationToken以完成身份验证。流程图如下:
从上面的描述和流程图中可以以下总结两个重点:
五、OAuth2AuthorizationCodeAuthenticationProvider
OAuth2LoginAuthenticationProvider里面还套了个OAuth2AuthorizationCodeAuthenticationProvider。它负责使用授权服务器的令牌端点对授权代码凭证进行身份验证。
- 验证授权码
首先从OAuth2AuthorizationCodeAuthenticationToken中的OAuth2AuthorizationExchange提取OAuth2AuthorizationResponse,判断是否是OAuth2异常响应。
如果不是,再和授权请求对象OAuth2AuthorizationRequest中的state值作一致性比较,一次OAuth2授权请求前后state必须保持一致。
-
获取OAuth2AccessToken
然后通过OAuth2AccessTokenResponseClient,底层用的是RestTemplate,按照OAuth2的token-uri封装就行了。后面的微信OAuth2网页授权中我们会定制该接口。 -
获取OAuth2User
拿到OAuth2AccessToken后跳回OAuth2LoginAuthenticationProvider。有了token自然能去调用个人信息接口user-info-uri了,Spring Security将这一流程抽象为OAuth2UserService接口:‘
这个接口很多时候底层也是通过RestTemplate实现的。而且在实际开发中OAuth2UserService大概率要自定义,同样在后面的微信OAuth2网页授权中我们会定制该接口。
额外的逻辑
OAuth2LoginAuthenticationProvider到这里就执行完了,后面处理的都是AbstractAuthenticationProcessingFilter的逻辑,和Form Login的逻辑流程一致=需要着重强调的是已认证OAuth2客户端对象会被存储起来,当前已认证的OAuth2AuthenticationToken会被存进安全上下文SecurityContext中。