Spring Cloud Security Oauth2

主要过滤器

ClientCredentialsTokenEndpointFilter

作用

首先进行过滤

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)req;
        HttpServletResponse response = (HttpServletResponse)res;
        if (!this.requiresAuthentication(request, response)) {
            chain.doFilter(request, response);
        } else {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Request is to process authentication");
            }

            Authentication authResult;
            try {
                authResult = this.attemptAuthentication(request, response);
                if (authResult == null) {
                    return;
                }

                this.sessionStrategy.onAuthentication(authResult, request, response);
            } catch (InternalAuthenticationServiceException var8) {
                this.logger.error("An internal error occurred while trying to authenticate the user.", var8);
                this.unsuccessfulAuthentication(request, response, var8);
                return;
            } catch (AuthenticationException var9) {
                this.unsuccessfulAuthentication(request, response, var9);
                return;
            }

            if (this.continueChainBeforeSuccessfulAuthentication) {
                chain.doFilter(request, response);
            }

            this.successfulAuthentication(request, response, chain, authResult);
        }
    }

从请求中获取 client_id,client_id_secret,
组成UsernamePasswordAuthenticationToken

 public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {

            String clientId = request.getParameter("client_id");
            String clientSecret = request.getParameter("client_secret");

            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(clientId, clientSecret);
            return this.getAuthenticationManager().authenticate(authRequest);
            }
        }

AuthenticationManager 具体的鉴权管理器

实现类一般是ProviderManager。而ProviderManager内部维护了一个List,
真正的身份认证是由一系列AuthenticationProvider去完成。而AuthenticationProvider
的常用实现类则是DaoAuthenticationProvider,DaoAuthenticationProvider
内部又聚合了一个UserDetailsService接口,UserDetailsService才是获取用户详细信息的最终接口。

之后验证请求到了 TokenEndpoint

   @RequestMapping(        value = {"/oauth/token"},        method = {RequestMethod.POST}    )
    public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId);
        ...
        TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient);
        ...
        OAuth2AccessToken token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest);
        ...
        return getResponse(token);
    }

使用 TokenGranter 来计算token

TokenGranter的设计思路是使用CompositeTokenGranter管理一个List列表,
每一种grantType对应一个具体的真正授权者,通过grantType来区分是否是各自的授权类型。


ResourceOwnerPasswordTokenGranter 账号密码
AuthorizationCodeTokenGranter 授权码模式
ClientCredentialsTokenGranter 客户端模式
ImplicitTokenGranter 简化模式
RefreshTokenGranter 刷新token专用

每一种token时实现了 TokenGranter接口

public interface TokenGranter {
    OAuth2AccessToken grant(String var1, TokenRequest var2);
}

实际验证的TokenGranter继承自抽象类 AbstractTokenGranter

public abstract class AbstractTokenGranter implements TokenGranter {
    protected final Log logger = LogFactory.getLog(this.getClass());
    private final AuthorizationServerTokenServices tokenServices;
    private final ClientDetailsService clientDetailsService;
    private final OAuth2RequestFactory requestFactory;
    private final String grantType;


    public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {
    }

    protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest tokenRequest) {
        return this.tokenServices.createAccessToken(this.getOAuth2Authentication(client, tokenRequest));
    }

    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
    }

    protected void validateGrantType(String grantType, ClientDetails clientDetails) {
    }

    protected AuthorizationServerTokenServices getTokenServices() {
    }

    protected OAuth2RequestFactory getRequestFactory() {
    }
}

Token具体的刷新创建由AuthorizationServerTokenServices 来实现

public interface AuthorizationServerTokenServices {
    OAuth2AccessToken createAccessToken(OAuth2Authentication var1) throws AuthenticationException;

    OAuth2AccessToken refreshAccessToken(String var1, TokenRequest var2) throws AuthenticationException;

    OAuth2AccessToken getAccessToken(OAuth2Authentication var1);
}

默认的TokenService


public class DefaultTokenServices implements AuthorizationServerTokenServices, ResourceServerTokenServices, ConsumerTokenServices, InitializingBean {
    private int refreshTokenValiditySeconds = 2592000;
    private int accessTokenValiditySeconds = 43200;
    private boolean supportRefreshToken = false;
    private boolean reuseRefreshToken = true;
    private TokenStore tokenStore;
    private ClientDetailsService clientDetailsService;
    private TokenEnhancer accessTokenEnhancer;
    private AuthenticationManager authenticationManager;

    public DefaultTokenServices() {
    }

    public void afterPropertiesSet() throws Exception {
        Assert.notNull(this.tokenStore, "tokenStore must be set");
    }

    @Transactional
    public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {

    }

    @Transactional(
        noRollbackFor = {InvalidTokenException.class, InvalidGrantException.class}
    )
    public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest tokenRequest) throws AuthenticationException {

    }

    public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
        return this.tokenStore.getAccessToken(authentication);
    }

    private OAuth2Authentication createRefreshedAuthentication(OAuth2Authentication authentication, TokenRequest request) {
       }


    public OAuth2AccessToken readAccessToken(String accessToken) {
        return this.tokenStore.readAccessToken(accessToken);
    }

    public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException, InvalidTokenException {
    }

    public String getClientId(String tokenValue) {
    }

    public boolean revokeToken(String tokenValue) {
    }

    private OAuth2RefreshToken createRefreshToken(OAuth2Authentication authentication) {
    }

    private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication, OAuth2RefreshToken refreshToken) {
    }

    ...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值