oauth2 增加token 返回参数_我扒了半天源码,终于找到了Oauth2自定义处理结果的最佳方案!...

论坛 期权论坛     
选择匿名的用户   2021-5-26 13:29   2467   0
<div>
<p></p>
<div style="text-align:center;">
  <img alt="75a99914acd794e5660b59772db57576.png" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-ec5db13d84c67cbc51ea60bc6774d17c.png">
</div>
<blockquote>
   在《微服务权限终极解决方案,Spring Cloud Gateway &#43; Oauth2 实现统一认证和鉴权!》一文中我们介绍了Oauth2在微服务中的使用,但是我们没有自定义Oauth2默认的处理结果。有时候我们真的很希望Oauth2中的认证授权能返回我们指定格式的结果,比如登录认证的结果、网关鉴权不通过的结果等等。本文将详细介绍Oauth2中自定义处理结果的方案,希望对大家有所帮助!
</blockquote>
<p>SpringCloud实战电商项目mall-swarm(5.1k&#43;star)地址:https://github.com/macrozheng/mall-swarm</p>
<h2>解决什么问题</h2>
<blockquote>
   自定义Oauth2处理结果,主要是为了统一接口返回信息的格式,从下面几个方面着手。
</blockquote>
<ul><li>自定义Oauth2登录认证成功和失败的返回结果;</li><li>JWT令牌过期或者签名不正确,网关认证失败的返回结果;</li><li>携带过期或者签名不正确的JWT令牌访问白名单接口,网关直接认证失败。</li></ul>
<h2>自定义登录认证结果</h2>
<h3>认证成功返回结果</h3>
<ul><li>我们先来看看默认的返回结果,访问Oauth2登录认证接口:http://localhost:9201/auth/oauth/token</li></ul>
<p></p>
<div style="text-align:center;">
  <img alt="56f74da25f989489d4368df5fa2cfd72.png" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-3c34ee413b7969b582f53504bf8df6af.png">
</div>
<ul><li>我们之前使用的都是统一的通用返回结果<code>CommonResult</code>,Oauth2的这个结果显然不符合,需要统一下,通用返回结果格式如下;</li></ul>
<div class="blockcode">
  <pre class="blockcode"><code>/**
* 通用返回对象
* Created by macro on 2019/4/19.
*/
public class CommonResult&lt;T&gt; {<!-- -->
    private long code;
    private String message;
    private T data;
}</code></pre>
</div>
<ul><li>其实我们只要找到一个关键类就可以自定义Oauth2的登录认证接口了,它就是<code>org.springframework.security.oauth2.provider.endpoint.TokenEndpoint</code>,其中定义了我们非常熟悉的登录认证接口,我们只要自己重写登录认证接口,直接调用默认的实现逻辑,然后把默认返回的结果处理下即可,下面是默认的实现逻辑;</li></ul>
<div class="blockcode">
  <pre class="blockcode"><code>&#64;FrameworkEndpoint
public class TokenEndpoint extends AbstractEndpoint {<!-- -->

    &#64;RequestMapping(value &#61; &#34;/oauth/token&#34;, method&#61;RequestMethod.POST)
    public ResponseEntity&lt;OAuth2AccessToken&gt; postAccessToken(Principal principal, &#64;RequestParam
    Map&lt;String, String&gt; parameters) throws HttpRequestMethodNotSupportedException {<!-- -->

        if (!(principal instanceof Authentication)) {<!-- -->
            throw new InsufficientAuthenticationException(
                    &#34;There is no client authentication. Try adding an appropriate authentication filter.&#34;);
        }

        String clientId &#61; getClientId(principal);
        ClientDetails authenticatedClient &#61; getClientDetailsService().loadClientByClientId(clientId);

        TokenRequest tokenRequest &#61; getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient);

        if (clientId !&#61; null &amp;&amp; !clientId.equals(&#34;&#34;)) {<!-- -->
            // Only validate the client details if a client authenticated during this
            // request.
            if (!clientId.equals(tokenRequest.getClientId())) {<!-- -->
                // double check to make sure that the client ID in the token request is the same as that in the
                // authenticated client
                throw new InvalidClientException(&#34;Given client ID does not match authenticated client&#34;);
            }
        }
        if (authenticatedClient !&#61; null) {<!-- -->
            oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
        }
        if (!StringUtils.hasText(tokenRequest.getGrantType())) {<!-- -->
            throw new InvalidRequestException(&#34;Missing grant type&#34;);
        }
        if (tokenRequest.getGrantType().equals(&#34;implicit&#34;)) {<!-- -->
            throw new InvalidGrantException(&#34;Implicit grant type not supported from token endpoint&#34;);
        }

        if (isAuthCodeRequest(parameters)) {<!-- -->
            // The scope was requested or determined during the authorization step
            if (!tokenRequest.getScope().isEmpty()) {<!-- -->
                logger.debug(&#34;Clearing scope of incoming token request&#34;);
                tokenRequest.setScope(Collections.&lt;String&gt; emptySet());
            }
        }

        if (isRefreshTokenRequest(parameters)) {<!-- -->
            // A refresh token has its own default scopes, so we should ignore any added by the factory here.
            tokenRequest.setScope(OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)));
        }

        OAuth2Acc
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP