美文网首页
Spring Security OAuth2 源码分析1 - T

Spring Security OAuth2 源码分析1 - T

作者: ninetxie | 来源:发表于2018-09-29 20:09 被阅读0次

    通过请求 oauth/token 来获取 token。大致为以下流程:

    1. 从 principal 中获取 clientId, 进而装载 ClientDetails
    2. 从 parameters 中获取 clientId、scope、grantType 以组装 TokenRequest
    3. 校验 Client 信息。
    4. 根据 grantType 设置 TokenRequest 的 scope。
    5. 通过令牌授予者获取 Token

    下面我们通过源码来学习整个流程。

    @FrameworkEndpoint
    public class TokenEndpoint extends AbstractEndpoint {
        // 以下是核心部分代码...
        @RequestMapping(value = "/oauth/token", method=RequestMethod.POST)
        public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
    
            if (!(principal instanceof Authentication)) {
                throw new InsufficientAuthenticationException(
                        "There is no client authentication. Try adding an appropriate authentication filter.");
            }
    
            // 1. 从 principal 中获取 clientId, 进而 load client 信息
            String clientId = getClientId(principal);
            ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId);
    
            // 2. 从 parameters 中拿 clientId、scope、grantType 组装 TokenRequest
            TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient);
    
            // 3. 校验 client 信息
            if (clientId != null && !clientId.equals("")) {
                if (!clientId.equals(tokenRequest.getClientId())) {
                    // 双重校验: 确保从 principal 拿到的 client 信息与根据 parameters 得到的 client 信息一致
                    throw new InvalidClientException("Given client ID does not match authenticated client");
                }
            }
            if (authenticatedClient != null) {
                oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
            }
    
            // 4. 根据 grantType 设置 TokenRequest 的 scope。
            // 授权类型有: password 模式、authorization_code 模式、refresh_token 模式、client_credentials 模式、implicit 模式
            if (!StringUtils.hasText(tokenRequest.getGrantType())) {
                throw new InvalidRequestException("Missing grant type");
            }
            if (tokenRequest.getGrantType().equals("implicit")) {
                throw new InvalidGrantException("Implicit grant type not supported from token endpoint");
            }
    
            // 如果是授权码模式, 则清空 scope。 因为授权请求过程会确定 scope, 所以没必要传
            if (isAuthCodeRequest(parameters)) {
                if (!tokenRequest.getScope().isEmpty()) {
                    logger.debug("Clearing scope of incoming token request");
                    tokenRequest.setScope(Collections.<String> emptySet());
                }
            }
    
            // 如果是刷新 Token 模式, 解析并设置 scope
            if (isRefreshTokenRequest(parameters)) {
                tokenRequest.setScope(OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)));
            }
    
            // 5. 通过令牌授予者获取 token
            OAuth2AccessToken token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest);
            if (token == null) {
                throw new UnsupportedGrantTypeException("Unsupported grant type: " + tokenRequest.getGrantType());
            }
    
            return getResponse(token);
        }
        // ...
    }
    

    该系列文章:

    Spring Security OAuth2 源码分析1 - TokenEndpoint
    Spring Security OAuth2 源码分析2 - TokenGranter
    Spring Security OAuth2 源码分析3 - TokenServices

    持续更新中...

    相关文章

      网友评论

          本文标题:Spring Security OAuth2 源码分析1 - T

          本文链接:https://www.haomeiwen.com/subject/zimboftx.html