如何在spring oauth使用redis令牌存储中获取jwt令牌的解码详细信息

Posted

技术标签:

【中文标题】如何在spring oauth使用redis令牌存储中获取jwt令牌的解码详细信息【英文标题】:How to get decode details of jwt token in spring oauth use redis token store 【发布时间】:2021-02-15 22:42:29 【问题描述】:

我已经成功获得了使用令牌存储 JwtTokenStore(JwtAccessTokenStore) 的解码细节,但现在它需要使用 redis 以便我可以撤销令牌。

这里是我的代码:

@Bean
public TokenStore tokenStore() 
    return new RedisTokenStore(redisConnectionFactory);
    // return new JwtTokenStore(defaultAccessTokenConverter());


@Bean
public JwtAccessTokenConverter defaultAccessTokenConverter() 
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setAccessTokenConverter(new CustomJWTAccessTokenConverter());
    try 
        converter.afterPropertiesSet();
     catch (Exception e) 
        e.printStackTrace();
    
    converter.setKeyPair(this.keyPair());
   
    return converter;

还有我的 customjwtaccesstokenconverter :

public class CustomJWTAccessTokenConverter extends DefaultAccessTokenConverter  

@Override
public OAuth2Authentication extractAuthentication(Map<String, ?> claims) 
    OAuth2Authentication authentication
            = super.extractAuthentication(claims);
    authentication.setDetails(claims);
    return authentication;
   

令牌增强器:

@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) 
    Map<String, Object> setAdditionalInformation = (Map<String, Object>) authentication.getUserAuthentication().getDetails();
    ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(setAdditionalInformation);
    return accessToken;

我不知道,什么时候使用 redistokenstore。它没有转到 CustomJWTAccessTokenConverter,因为当我尝试获取其他信息(decodeDetails)时返回 null。

 OAuth2Authentication authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
            OAuth2AuthenticationDetails authenticationDetails = (OAuth2AuthenticationDetails) authentication.getDetails();
            Map<String, Object> decodeDetails = (Map<String, Object>) authenticationDetails.getDecodedDetails();

【问题讨论】:

【参考方案1】:

您还需要配置令牌增强器 -

@Bean
public TokenStore tokenStore() 
    return new RedisTokenStore(redisConnectionFactory);
    // return new JwtTokenStore(defaultAccessTokenConverter());


@Bean
public JwtAccessTokenConverter defaultAccessTokenConverter() 
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setAccessTokenConverter(new CustomJWTAccessTokenConverter());
    try 
        converter.afterPropertiesSet();
     catch (Exception e) 
        e.printStackTrace();
    
    converter.setKeyPair(this.keyPair());
   
    return converter;


@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception 
    endpoints
        // some code here
        .tokenEnhancer(tokenEnhancer());


@Bean
@Primary
public AuthorizationServerTokenServices tokenServices() 
    DefaultTokenServices tokenServices = new DefaultTokenServices();
   
    tokenServices.setTokenEnhancer(tokenEnhancer());
    return tokenServices;


// Beans beans beans

@Bean
public TokenEnhancer tokenEnhancer() 
    return new YourCustomTokenEnhancer();

【讨论】:

我已经创建了它。 `@Bean`public TokenEnhancer customTokenEnhancer() `return new CustomTokenEnhancer();` 好的,您是否在 AuthorizationServerEndpointsConfigurer 中注册了它,您还需要将您的自定义 AuthorizationServerTokenServices 优先于默认值。 是的,这里:public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception TokenEnhancerChain chain = new TokenEnhancerChain();chain.setTokenEnhancers(Arrays.asList(customTokenEnhancer(), defaultAccessTokenConverter()));endpoints.exceptionTranslator(new OAuth2ExceptionTranslator()).tokenStore(tokenStore()).authenticationManager(authenticationManager).tokenEnhancer(chain);`【参考方案2】:

已解决,但不确定是否正确。

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception 
    TokenEnhancerChain chain = new TokenEnhancerChain();
    chain.setTokenEnhancers(Arrays.asList(customTokenEnhancer(), defaultAccessTokenConverter()));

    endpoints.exceptionTranslator(new OAuth2ExceptionTranslator())
            .tokenStore(tokenStore())
            .tokenEnhancer(chain)
            .authenticationManager(authenticationManager);


@Bean
public TokenStore tokenStore() 
    return new RedisTokenStore(redisConnectionFactory);


@Bean
@Primary
public AuthorizationServerTokenServices tokenServices() 
    TokenEnhancerChain chain = new TokenEnhancerChain();
    chain.setTokenEnhancers(Arrays.asList(customTokenEnhancer(), defaultAccessTokenConverter()));

    DefaultTokenServices tokenServices = new DefaultTokenServices();
    tokenServices.setTokenEnhancer(chain);
    tokenServices.setTokenStore(new JwtTokenStore(defaultAccessTokenConverter()));
    tokenServices.setSupportRefreshToken(false);
    return tokenServices;

如果有人有更好的想法,请发表评论。

【讨论】:

以上是关于如何在spring oauth使用redis令牌存储中获取jwt令牌的解码详细信息的主要内容,如果未能解决你的问题,请参考以下文章

如何使用没有密码的spring生成oauth令牌

如何使用 Spring Cloud Security 实现 OAuth2“令牌交换”

如何使用 Spring boot keycloak 适配器 + spring security 强制更新 oAuth 令牌(访问令牌 + 刷新令牌)。?

如何在spring security oauth2中分离访问令牌和刷新令牌端点

Spring Boot + OAuth2 + Google Login - 如何实现注销

Spring security oauth 令牌提取