实用干货:OAuth2授权请求是如何构造和执行的发起OAuth2授权请求的方法sendRedirectForAuthorization。不过这个方法并不详细,所以今天继续上篇文章来补一下这个坑。2.sendRedirectForAuthorizationsendRedirectForAuthorization方法代码不多,主要作用是授权第三方平台重定向访??问。它的所有逻辑都与OAuth2AuthorizationRequest有关,所以我们不能低估OAuth2AuthorizationRequest,必须把握OAuth2AuthorizationRequest是怎么来的,为什么要用。OAuth2AuthorizationRequestResolver需要分析分析类OAuth2AuthorizationRequestResolver。它的核心方法有两个重载,这里分析一下就够了。@OverridepublicOAuth2AuthorizationRequestresolve(HttpServletRequestrequest){//通过uri路径参数获取registrationId/oauth2/authorization/{registrationId}StringregistrationId=this.resolveRegistrationId(request);//然后到request对象request中提取key为action的参数,默认值是loginStringredirectUriAction=getAction(request,"login");//然后进入基本分析方法method是最后一个方法,从/oauth2/authorization的根方法中提取OAuth2AuthorizationRequest。代码太多了,我尽量用通俗易懂的方式来说明。resolve方法会根据不同的授权方式(AuthorizationGrantType)组装不同的OAuth2AuthorizationRequests。3.OAuth2AuthorizationRequest接下来是OAuth2.0协议的核心。也许您的定制参考将来会来自这里。这是要考的知识点。我将OAuth2AuthorizationRequestResolver对各种授权方式下的OAuth2AuthorizationRequest对象的分析做一个完整的总结。大致分为以下两部分:3.1结合AuthorizationGrantType确定的不同AuthorizationGrantTypes下的OAuth2AuthorizationRequest。涉及的成员变量有:authorizationGrantType,来自配置spring.security.client.registration.{registrationId}.authorizationGrantType。responseType,由authorizationGrantType的值决定,参考下面的JSON。additionalParameters,当authorizationGrantType值为authorization_code时需要一些额外的参数,参考下面的JSON。属性,不同的authorizationGrantTypes有不同的属性。类似{registrationId}的形式表示{registrationId}是一个变量,比如registrationId=gitee。OAuth2客户端配置spring.security.client.registration.{registrationId}的前缀有以下五种情况。当scope不包含openid且client-authentication-method不为none时,以上四个参数:{"authorizationGrantType":"authorization_code","re??sponseType":"code","additionalParameters":{},"attributes":{"registration_id":"{registrationId}"}}复制代码当scope中包含openid且client-authentication-method不为none时,以上四个参数:{"authorizationGrantType":"authorization_code","re??sponseType":"code","additionalParameters":{"nonce":"{nonce}的哈希值"},"attributes":{"registration_id":"{registrationId}","nonce":"{nonce}"}}当范围不包含openid和client当-authentication-method为none时,以上四个参数:{"authorizationGrantType":"authorization_code","re??sponseType":"code","additionalParameters":{"code_challenge":"{codeVerifier}的哈希值",//code_challenge_method不是SHA256时可能没有这个key"code_challenge_method":"S256(如果是SHA256算法)"},"attributes":{"registration_id":"{registrationId}","code_verifier":"Base64生成安全{codeVerifier}"}}时范围包含当openid和client-authentication-method都为none时,以上四个参数:",//code_challenge_method如果不是SHA256可能没有这个key"code_challenge_method":"S256(如果是SHA256算法)","nonce":"{nonce}的哈希值"},"attributes":{"registration_id":"{registrationId}","code_verifier":"Base64生成的安全{codeVerifier}","nonce":"{nonce}"}}隐式要简单得多:{"authorizationGrantType":"implicit","responseType":"token","attributes":{}}3.2固定规则上面部分是OAuth2AuthorizationRequest在各种AuthorizationGrantTypes下的成员变量个性化取值策略,几个参数的规则是固定的:clientId来自配置,是第三方平台给我们的唯一标识。authorizationUri来自配置,用于构造向第三方发起的请求URL。scopes来源于configuration,是第三方平台授权的scope,可以理解为角色。自动生成状态以防止csrf攻击。authorizationRequestUri向第三方平台发起授权请求,可以直接通过OAuth2AuthorizationRequest构造类设置,也可以通过上述authorizationUri等参数生成。后面会分析构造机制。redirectUri当第三方平台收到OAuth2AuthorizationRequest时,第三方平台会回调这个URI来响应授权请求,后面会分析其机制。如果authorizationRequestUri构造机制没有明确提供authorizationRequestUri,则OAuth2AuthorizationRequest中的responseTypeclientIdscopesstateredirectUriadditionalParameters会按照如下规则拼接成authorizationUri参数串。参数字符串的键和值必须经过URI编码。authorizationUri?response_type={responseType.getValue()}&client_id={clientId}&scope={scopeselementacharacterinterval}&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响应。那么SpringSecurityOAuth2是如何处理第三方回调的呢?注意:码农哥为你揭晓答案。
