关于java: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-methodnone时上述四个参数:

{
  "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-methodnone时上述四个参数:

{
  "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等参数来生成,稍后会把结构机制剖析一波。
  • redirectUriOAuth2AuthorizationRequest被第三方平台收到后,第三方平台会回调这个URI来对受权申请进行相应,稍后也会来剖析其机制。

authorizationRequestUri的构建机制

如果不显式提供authorizationRequestUri就会通过OAuth2AuthorizationRequest中的

  • responseType
  • clientId
  • scopes
  • state
  • redirectUri
  • additionalParameters

    依照上面的规定进行拼接成authorizationUri的参数串,参数串的keyvalue都要进行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,有两种默认值loginauthorize ,当/oauth2/authorization申请中蕴含了action参数时会依据action的值进行填充。
  • registrationId 这个就不必多说了。

4. 总结

通过对OAuth2AuthorizationRequest申请对象的规定进行详细分析,咱们应该能大抵的晓得的过滤器OAuth2AuthorizationRequestRedirectFilter流程:

  1. 通过客户端配置构建ClientRegistration,后续能够进行长久化。
  2. 拦挡/oauth2/authorization申请并结构OAuth2AuthorizationRequest,而后重定向到authorizationRequestUri进行申请受权。
  3. 第三方通过redirect_uri进行相应。

那么Spring Security OAuth2如何对第三方的回调相应进行解决呢?关注:码农小胖哥 为你揭晓这个答案。

关注公众号:Felordcn 获取更多资讯

集体博客:https://felord.cn

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理