Spring Security 实战干货:OAuth2授权请求是如何构建并执行的
在Spring Security 实战干货:客户端OAuth2授权请求的入口中我们找到了拦截OAuth2授权请求入口/oauth2/authorization
的过滤器OAuth2AuthorizationRequestRedirectFilter
,并找到了真正发起OAuth2授权请求的方法sendRedirectForAuthorization
。但是这个方法并没有细说,所以今天接着上一篇把这个坑给补上。
2. sendRedirectForAuthorization
这个sendRedirectForAuthorization
方法没多少代码,它的主要作用就是向第三方平台进行授权重定向访问。它所有的逻辑都和OAuth2AuthorizationRequest
有关,因此我们对OAuth2AuthorizationRequest
进行轻描淡写是不行的,我们必须掌握OAuth2AuthorizationRequest
是怎么来的,干嘛用的。
OAuth2AuthorizationRequestResolver
这就需要去分析解析类OAuth2AuthorizationRequestResolver
,其核心方法有两个重载,这里分析一个就够了。
@Override public OAuth2AuthorizationRequest resolve(HttpServletRequest request) { // registrationId是通过uri路径参数/oauth2/authorization/{registrationId}获得的 String registrationId = this.resolveRegistrationId(request); // 然后去请求对象request中提取key为action的参数,默认值是login String redirectUriAction = getAction(request, "login"); // 然后进入根本的解析方法 return resolve(request, registrationId, redirectUriAction); }
上面方法里面的resolve(request, registrationId, redirectUriAction)
方法才是最终从/oauth2/authorization
提取OAuth2AuthorizationRequest
的根本方法。代码太多但是我尽量通俗易懂的来进行图解。resolve
方法会根据不同的授权方式(AuthorizationGrantType
)来组装不同的OAuth2AuthorizationRequest
。
3. OAuth2AuthorizationRequest
接下来就是OAuth2.0协议的核心重中之重了,可能以后你定制化的参考就来自这里,这是圈起来要考的知识点。我会对OAuth2AuthorizationRequestResolver
在各种授权方式下的OAuth2AuthorizationRequest
对象的解析进行一个完全的总结归纳。大致分为以下两部分:
3.1 由AuthorizationGrantType决定的
在不同AuthorizationGrantType
下对OAuth2AuthorizationRequest
的梳理。涉及到的成员变量有:
authorizationGrantType
,来自配置spring.security.client.registration.{registrationId}.authorizationGrantType
。responseType
, 由authorizationGrantType
的值决定,参考下面的JSON。additionalParameters
,当authorizationGrantType
值为authorization_code
时需要额外的一些参数,参考下面JSON 。attributes
,不同的authorizationGrantType
存在不同的属性。
其中类似
{registrationId}
的形式表示{registrationId}
是一个变量,例如registrationId=gitee
。
在OAuth2客户端配置spring.security.client.registration.{registrationId}
的前缀中有以下五种情况。
当 scope
不包含openid
而且client-authentication-method
不为none
时上述四个参数:
{ "authorizationGrantType": "authorization_code", "responseType": "code", "additionalParameters": {}, "attributes": { "registration_id": "{registrationId}" } }
当 scope
包含openid
而且client-authentication-method
不为none
时上述四个参数:
{ "authorizationGrantType": "authorization_code", "responseType": "code", "additionalParameters": { "nonce": "{nonce}的Hash值" }, "attributes": { "registration_id": "{registrationId}", "nonce": "{nonce}" } }
当 scope
不包含openid
而且client-authentication-method
为none
时上述四个参数:
{ "authorizationGrantType": "authorization_code", "responseType": "code", "additionalParameters": { "code_challenge": "{codeVerifier}的Hash值", // code_challenge_method 当不是SHA256可能没有该key "code_challenge_method": "S256(如果是SHA256算法的话)" }, "attributes": { "registration_id": "{registrationId}", "code_verifier": "Base64生成的安全{codeVerifier}" } }
当 scope
包含openid
而且client-authentication-method
为none
时上述四个参数:
{ "authorizationGrantType": "authorization_code", "responseType": "code", "additionalParameters": { "code_challenge": "{codeVerifier}的Hash值", // code_challenge_method 当不是SHA256可能没有该key "code_challenge_method": "S256(如果是SHA256算法的话)", "nonce": "{nonce}的Hash值" }, "attributes": { "registration_id": "{registrationId}", "code_verifier": "Base64生成的安全{codeVerifier}", "nonce": "{nonce}" } }
implicit
下要简单的多:
{ "authorizationGrantType": "implicit", "responseType": "token", "attributes": {} }
3.2 固定规则部分
上面是各种不同AuthorizationGrantType
下的OAuth2AuthorizationRequest
的成员变量个性化取值策略, 还有几个参数的规则是固定的:
clientId
来自于配置,是第三方平台给予我们的唯一标识。authorizationUri
来自于配置,用来构造向第三方发起的请求URL。scopes
来自于配置,是第三方平台给我们授权划定的作用域,可以理解为角色。state
自动生成的,为了防止csrf 攻击。authorizationRequestUri
向第三方平台发起授权请求的,可以直接通过OAuth2AuthorizationRequest
的构建类来设置或者通过上面的authorizationUri
等参数来生成,稍后会把构造机制分析一波。redirectUri
当OAuth2AuthorizationRequest
被第三方平台收到后,第三方平台会回调这个URI来对授权请求进行相应,稍后也会来分析其机制。
authorizationRequestUri的构建机制
如果不显式提供authorizationRequestUri
就会通过OAuth2AuthorizationRequest
中的
responseType
clientId
scopes
state
redirectUri
additionalParameters
按照下面的规则进行拼接成authorizationUri
的参数串,参数串的key
和value
都要进行URI编码。
authorizationUri?response_type={responseType.getValue()}&client_id={clientId}&scope={scopes元素一个字符间隔}&state={state}&redirect_uri={redirectUri}&{additionalParameter展开进行同样规则的KV参数串}
然后OAuth2AuthorizationRequestRedirectFilter
负责重定向到authorizationRequestUri
向第三方请求授权。
redirectUri
第三方收到响应会调用redirectUri
,回调也是有一定默认规则的,它遵循{baseUrl}/{action}/oauth2/code/{registrationId}
的路径参数规则。
baseUrl
是从我们/oauth2/authorization
请求中提取的基础请求路径。action
,有两种默认值login
、authorize
,当/oauth2/authorization
请求中包含了action
参数时会根据action
的值进行填充。registrationId
这个就不用多说了。
4. 总结
通过对OAuth2AuthorizationRequest
请求对象的规则进行详细分析,我们应该能大致的知道的过滤器OAuth2AuthorizationRequestRedirectFilter
流程:
- 通过客户端配置构建
ClientRegistration
,后续可以进行持久化。 - 拦截
/oauth2/authorization
请求并构造OAuth2AuthorizationRequest
,然后重定向到authorizationRequestUri
进行请求授权。 - 第三方通过
redirect_uri
进行相应。
那么Spring Security OAuth2如何对第三方的回调相应进行处理呢?关注:码农小胖哥
为你揭晓这个答案。
关注公众号:Felordcn获取更多资讯

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
JDK的命令行工具详解
一、概述 JDK的命令行工具指的是jdk的bin目录中的一些可执行工具,除了常用的java、javac之外,还有很多其他可执行工具,主要包括用于监视虚拟机和故障处理的工具。这些故障处理工具被Sun公司作为“礼物”附赠给JDK的使用者。 主要的工具和功能如下: 名称 中文名 全拼 主要作用 jps 虚拟机进程状况工具 JVM ProcessStatus Tool 显示指定系统内所有虚拟机进程 jstat 虚拟机统计信息监视工具 JVM Statistics Monitoring Tool 用于收集虚拟机各方面的运行数据 jinfo Java配置信息工具 Configuration Info for Java 实时地查看和调整虚拟机各项参数 jmap Java内存映像工具 Memory Map for Java 用于生成堆转储快照 jhat 虚拟机堆转储快照分析工具 JVM Heap Analysis Tool 与jmap搭配使用,来分析jmap生成的堆转储快照 jstack Java堆栈跟踪工具 Stack Trace for Java 于生成虚拟机当前时刻的线程快照(一般称为threa...
- 下一篇
Reactor中的Thread和Scheduler
简介 今天我们要介绍的是Reactor中的多线程模型和定时器模型,Reactor之前我们已经介绍过了,它实际上是观察者模式的延伸。 所以从本质上来说,Reactor是和多线程无关的。你可以把它用在多线程或者不用在多线程。 今天将会给大家介绍一下如何在Reactor中使用多线程和定时器模型。 Thread多线程 先看一下之前举的Flux的创建的例子: Flux<String> flux = Flux.generate( () -> 0, (state, sink) -> { sink.next("3 x " + state + " = " + 3*state); if (state == 10) sink.complete(); return state + 1; }); flux.subscribe(System.out::println); 可以看到,不管是Flux generator还是subscriber,他们实际上都是运行在同一个线程中的。 如果我们想让subscribe发生在一个新的线程中,我们需要新启动一个线程,然后在线程内部进行subscribe操...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2整合Redis,开启缓存,提高访问速度