在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 获取更多资讯
集体博客:https://felord.cn
发表回复