Search code examples
spring-securityjwtspring-oauth2

How to get decode details of jwt token in spring oauth use redis token store


i've success got decode details use token store JwtTokenStore(JwtAccessTokenStore), but now it required to use redis so that i can revoke token.

here my code :

@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;
}

and my customjwtaccesstokenconverter :

public class CustomJWTAccessTokenConverter extends DefaultAccessTokenConverter  {

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

token enhancer :

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

i have no idea, when use redistokenstore. it didn't went to CustomJWTAccessTokenConverter because of that when i was trying to get additional information (decodeDetails) returned null.

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

Solution

  • it resolved, but not sure it is the right way or not.

    @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;
    }
    

    if anyone has better idea please comment.