欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Oauth2AuthenticationProcassingFilter解析

程序员文章站 2022-05-08 14:20:30
...
Spring Security Outh2的过滤器链如下图所示:
Oauth2AuthenticationProcassingFilter解析
            
    
    博客分类: 跟我学Spring Security系列 spring securityoauth2 
 
其中 SecurityContextPersistenceFilter用的是 NullSecurityContextRepository。 也就是说SecurityContextPersistenceFilter没有持久化SecurityContext, 这一步始终都是获取一个空的SecurityContext存放在SpringSecurityContextHolder中。
 
那么真正解析请求头部或者查询参数 Authorization 令牌的是什么呢? 是由 Oauth2AuthenticationProcassingFilter 进行解析的。
 
Oauth2AuthenticationProcassingFilter解析
 
TokenExtractor Token抽取器(比如:BearerTokenExtractor ), 用于解析参数获取Token信息, 返回PreAuthenticatedAuthenticationToken; 
此时返回的 PreAuthenticatedAuthenticationToken 对象如下图所示
 
Oauth2AuthenticationProcassingFilter解析
            
    
    博客分类: 跟我学Spring Security系列 spring securityoauth2 
 
调用AuthenticationDetailsSource构建 details, 代码如下
public class OAuth2AuthenticationDetailsSource implements
        AuthenticationDetailsSource<HttpServletRequest, OAuth2AuthenticationDetails> {
 
    public OAuth2AuthenticationDetails buildDetails(HttpServletRequest context) {
        return new OAuth2AuthenticationDetails(context);
    }
 
}
这一步执行完后 authentication状态如下:

Oauth2AuthenticationProcassingFilter解析
            
    
    博客分类: 跟我学Spring Security系列 spring securityoauth2 
认证授权, 
 
调用 OAuth2AuthenticationManager对之前的authentication进行认证。
 
Authentication authResult = authenticationManager.authenticate(authentication);
 
对认证的逻辑展开下说明:
 
调用ResourceServerTokenServices (例如, DefaultTokenServices )中的loadAuthentication方法认证。其中有个重要的TokenStore, 我这里用的是JdbcTokenStore, 用于存取Token信息。还有ClientDetailsService接口, 用于判断clientId是否满足。
 
除了DefaultTokenServices外, 默认实现还有如下:

Oauth2AuthenticationProcassingFilter解析
            
    
    博客分类: 跟我学Spring Security系列 spring securityoauth2 
 
public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException,
            InvalidTokenException {
        OAuth2AccessToken accessToken = tokenStore.readAccessToken(accessTokenValue);
        if (accessToken == null) {
            throw new InvalidTokenException("Invalid access token: " + accessTokenValue);
        }
        else if (accessToken.isExpired()) {
            tokenStore.removeAccessToken(accessToken);
            throw new InvalidTokenException("Access token expired: " + accessTokenValue);
        }
 
        OAuth2Authentication result = tokenStore.readAuthentication(accessToken);
        if (result == null) {
            // in case of race condition
            throw new InvalidTokenException("Invalid access token: " + accessTokenValue);
        }
        if (clientDetailsService != null) {
            String clientId = result.getOAuth2Request().getClientId();
            try {
                clientDetailsService.loadClientByClientId(clientId);
            }
            catch (ClientRegistrationException e) {
                throw new InvalidTokenException("Client not valid: " + clientId, e);
            }
        }
        return result;
    }
认证成功后,调用Spring Security核心类 SecurityContextHolder 初始化Context上下文信息。
SecurityContextHolder.getContext().setAuthentication(authResult);
  • Oauth2AuthenticationProcassingFilter解析
            
    
    博客分类: 跟我学Spring Security系列 spring securityoauth2 
  • 大小: 155.5 KB
  • Oauth2AuthenticationProcassingFilter解析
            
    
    博客分类: 跟我学Spring Security系列 spring securityoauth2 
  • 大小: 86.1 KB
  • Oauth2AuthenticationProcassingFilter解析
            
    
    博客分类: 跟我学Spring Security系列 spring securityoauth2 
  • 大小: 91.9 KB
  • Oauth2AuthenticationProcassingFilter解析
            
    
    博客分类: 跟我学Spring Security系列 spring securityoauth2 
  • 大小: 24.6 KB