Spring Security 实战干货:OAuth2登录获取Token的核心逻辑

1. 前言
在上一篇Spring Security 实战干货:OAuth2授权回调的核心认证流程中,我们讲了当第三方同意授权后会调用redirectUri发送回执给我们的服务器。我们的服务器拿到一个中间授信凭据会再次进行认证,目的是为了获取Token。而这个逻辑由OAuth2LoginAuthenticationProvider负责,经过上一文的分析后我们发现获取Token的具体逻辑由OAuth2AuthorizationCodeAuthenticationProvider来完成,今天就把它的流程搞清楚,来看看Spring Security OAuth2 认证授权获取Token的具体步骤。
注意:本Spring Security干货系列教程的OAuth2相关部分是在Spring Security 5.x版本的。
2. OAuth2AuthorizationCodeAuthenticationProvider
该类是AuthenticationProvider针对OAuth 2.0中Authorization Code Grant模式的实现。关于AuthenticationProvider有必要简单强调一下,它已经多次在Spring Security干货系列中出现,十分重要!一定要去看看相关的分析和使用,它是你根据业务扩展认证方式渠道的重要入口。
2.1 OAuth2AccessTokenResponseClient
在该实现中包含了一个OAuth2AccessTokenResponseClient成员变量,它抽象了通过tokenUri端点从认证服务器获取Token的细节。你可以根据OAuth 2.0常用的四种模式来进行实现它, 以达到根据不同的策略来获取Token的能力。

在Spring Security 5中OAuth 2.0登录的配置中默认使用DefaultAuthorizationCodeTokenResponseClient。如果你想使用自定义实现的话可以通过HttpSecurity来配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.oauth2Login()
.tokenEndpoint()
// 注入自定义的 OAuth2AccessTokenResponseClient
.accessTokenResponseClient(authorizationCodeTokenResponseClient);
// 其它省略
}
接下来我们看看DefaultAuthorizationCodeTokenResponseClient实现的获取Token的逻辑:
@Override
public OAuth2AccessTokenResponse getTokenResponse(OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest) {
Assert.notNull(authorizationCodeGrantRequest, "authorizationCodeGrantRequest cannot be null");
// 1. 封装调用tokenUri所需要的请求参数RequestEntity
RequestEntity<?> request = this.requestEntityConverter.convert(authorizationCodeGrantRequest);
ResponseEntity<OAuth2AccessTokenResponse> response;
try {
// 2. 通过RestTemplate 发起请求获取 OAuth2AccessTokenResponse
response = this.restOperations.exchange(request, OAuth2AccessTokenResponse.class);
} catch (RestClientException ex) {
OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE,
"An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null);
throw new OAuth2AuthorizationException(oauth2Error, ex);
}
// 3. 解析 ResponseEntity 组织返回值 OAuth2AccessTokenResponse
OAuth2AccessTokenResponse tokenResponse = response.getBody();
if (CollectionUtils.isEmpty(tokenResponse.getAccessToken().getScopes())) {
// originally requested by the client in the Token Request
tokenResponse = OAuth2AccessTokenResponse.withResponse(tokenResponse)
.scopes(authorizationCodeGrantRequest.getClientRegistration().getScopes())
.build();
}
return tokenResponse;
}
这里的方式跟我另一个开源项目Payment Spring Boot的请求方式异曲同工,都是三个步骤:
- 组织参数
RequestEntity。 RestOperations发起请求。- 解析
ResponseEntity组织返回值。
如果有些的OAuth 2.0认证服务器获取Token的方式比较特殊你可以自行实现OAuth2AccessTokenResponseClient。
3. 总结
OAuth2AccessTokenResponseClient是OAuth2AuthorizationCodeAuthenticationProvider的核心要点。搞清楚它的作用和机制就可以了。这里我们总结一下OAuth2AuthorizationCodeAuthenticationProvider的认证过程:
- 检测未授信
OAuth2AuthorizationCodeAuthenticationToken的状态是否合法。 - 通过
OAuth2AccessTokenResponseClient请求OAuth 2.0认证服务器获取Token等信息。 - 组装认证过的授信
OAuth2AuthorizationCodeAuthenticationToken返回。
到此OAuth 2.0的登录流程就搞清楚了,读者可通过系列文章进行学习批判。我是:码农小胖哥,多多关注,获取实用的编程干货。
关注公众号:Felordcn 获取更多资讯
Spring Security 实战干货:OAuth2登录获取Token的核心逻辑的更多相关文章
- Spring Security 实战干货:使用 JWT 认证访问接口
(转载)原文链接:https://my.oschina.net/10000000000/blog/3127268 1. 前言 欢迎阅读Spring Security 实战干货系列.之前我讲解了如何编写 ...
- Spring Security 实战干货: 简单的认识 OAuth2.0 协议
1.前言 欢迎阅读 Spring Security 实战干货 系列文章 .OAuth2.0 是近几年比较流行的授权机制,对于普通用户来说可能每天你都在用它,我们经常使用的第三方登录大都基于 OAuth ...
- Spring Security 实战干货:图解用户是如何登录的
1. 前言 欢迎阅读Spring Security 实战干货系列文章,在集成Spring Security安全框架的时候我们最先处理的可能就是根据我们项目的实际需要来定制注册登录了,尤其是Http登录 ...
- Spring Security 实战干货:实现自定义退出登录
文章目录 1. 前言 2. 我们使用 Spring Security 登录后都做了什么 2. 退出登录需要我们做什么 3. Spring Security 中的退出登录 3.1 LogoutFilte ...
- Spring Security 实战干货:OAuth2第三方授权初体验
1. 前言 Spring Security实战干货系列 现在很多项目都有第三方登录或者第三方授权的需求,而最成熟的方案就是OAuth2.0授权协议.Spring Security也整合了OAuth2. ...
- Spring Security 实战干货:OAuth2授权请求是如何构建并执行的
在Spring Security 实战干货:客户端OAuth2授权请求的入口中我们找到了拦截OAuth2授权请求入口/oauth2/authorization的过滤器OAuth2Authorizati ...
- Spring Security 实战干货:客户端OAuth2授权请求的入口
1. 前言 在Spring Security 实战干货:OAuth2第三方授权初体验一文中我先对OAuth2.0涉及的一些常用概念进行介绍,然后直接通过一个DEMO来让大家切身感受了OAuth2.0第 ...
- Spring Security 实战干货:如何实现不同的接口不同的安全策略
1. 前言 欢迎阅读 Spring Security 实战干货 系列文章 .最近有开发小伙伴提了一个有趣的问题.他正在做一个项目,涉及两种风格,一种是给小程序出接口,安全上使用无状态的JWT Toke ...
- Spring Security 实战干货:图解Spring Security中的Servlet过滤器体系
1. 前言 我在Spring Security 实战干货:内置 Filter 全解析对Spring Security的内置过滤器进行了罗列,但是Spring Security真正的过滤器体系才是我们了 ...
随机推荐
- docker版mysql的使用和配置(2)——docker版mysql的dockerfile
既然目标是定制满足自己需要的dockerfile,那么就来看看mysql的dockerfile长什么样. dockerfile选择的是 https://github.com/mysql/mysql-d ...
- UML——状态图
状态图(Statechart Diagram),主要用于描述对象在其生命周期中基于事件的动态行为,显示了对象如何根据当前的状态对不同的事件(Events)作出反应(Action).一般我们用状态机来对 ...
- .Net Core 3.1浏览器后端服务(一) Web API项目搭建
一.前言 基于CefSharp开发的浏览器项目已有一段时间,考虑到后期数据维护需要Server端来管理,故开启新篇章搭建浏览器后端服务.该项目前期以梳理服务端知识为主,后期将配合CefSharp浏览器 ...
- linux学习之---在linux服务器上跑一段Java代码
经常在windows上进行开发,有时候,需要在Linux环境上跑一些程序测下代码,要怎么办才好嘞? 假设你对Java常用命令和linux常用命令已经基本熟悉,就可以直接按照以下步骤来啦,默认linux ...
- UVA 10294 项链与手镯 (置换)
Burnside引理:对于一个置换\(f\), 若一个着色方案\(s\)经过置换后不变,称\(s\)为\(f\)的不动点.将\(f\)的不动点数目记为\(C(f)\), 则可以证明等价类数目为\(C( ...
- Codeforces Round #676 (Div. 2)【ABCD】
比赛链接:https://codeforces.com/contest/1421 A. XORwice 题意 给出两个正整数 \(a.b\),计算 \((a \oplus x) + (b \oplus ...
- Codeforces Round #646 (Div. 2) B. Subsequence Hate(前缀和)
题目链接:https://codeforces.com/contest/1363/problem/B 题意 可以将 $01$ 串中的 $0$ 变为 $1$.$1$ 变为 $0$,问至少需要变换多少字符 ...
- Codeforces Round #668 (Div. 2) B. Array Cancellation (思维,贪心)
题意:有一个长度为\(n\)并且所有元素和为\(0\)的序列,你可以使\(a_{i}-1\)并且\(a_{j}+1\),如果\(i<j\),那么这步操作就是免费的,否则需要花费一次操作,问最少操 ...
- 国产网络测试仪MiniSMB - 如何配置VLAN数据流
国产网络测试仪MiniSMB(www.minismb.com)是复刻smartbits的IP网络性能测试工具,是一款专门用于测试智能路由器,网络交换机的性能和稳定性的软硬件相结合的工具.可以通过此以太 ...
- GO - go mod使用原理
Go Module 依赖管理 go mod使用 原理及使用ref: https://xuanwo.io/2019/05/27/go-modules/ go module的稳定路径: https://l ...