访问资源服务器控制器内的 Spring OAuth 2 JWT 有效负载?

我正在学习本教程,了解如何使用jwt设置spring boot oauth。它介绍了如何使用 Angular 解码 JWT 令牌,但是我们如何对其进行解码并访问资源服务器控制器内的自定义声明?

例如,使用JJWT可以像这样完成(基于本文):

    String subject = "HACKER";
    try {
        Jws jwtClaims = 
            Jwts.parser().setSigningKey(key).parseClaimsJws(jwt);

        subject = claims.getBody().getSubject();

        //OK, we can trust this JWT

    } catch (SignatureException e) {

        //don't trust the JWT!
    }

Spring有一个JWTAccessTokenConverter.decode()方法,但javadoc缺乏,它是受保护的。


答案 1

以下是我在Spring Boot中访问自定义JWT声明的方式:

1)让Spring将JWT内容复制到:Authentication

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends ResourceServerConfigurerAdapter{

    @Override
    public void configure(ResourceServerSecurityConfigurer config) {
        config.tokenServices( createTokenServices() );
    }

    @Bean
    public DefaultTokenServices createTokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore( createTokenStore() );
        return defaultTokenServices;
    }

    @Bean
    public TokenStore createTokenStore() {               
        return new JwtTokenStore( createJwtAccessTokenConverter() );
    }

    @Bean
    public JwtAccessTokenConverter createJwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();     
        converter.setAccessTokenConverter( new JwtConverter() );
        return converter;
    }

    public static class JwtConverter extends DefaultAccessTokenConverter implements JwtAccessTokenConverterConfigurer {

        @Override
        public void configure(JwtAccessTokenConverter converter) {
            converter.setAccessTokenConverter(this);
        }

        @Override
        public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
            OAuth2Authentication auth = super.extractAuthentication(map);
            auth.setDetails(map); //this will get spring to copy JWT content into Authentication
            return auth;
        }
    }
}

2) 访问代码中任何位置的令牌内容:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();        
Object details = authentication.getDetails();        
if ( details instanceof OAuth2AuthenticationDetails ){
    OAuth2AuthenticationDetails oAuth2AuthenticationDetails = (OAuth2AuthenticationDetails)details;

    Map<String, Object> decodedDetails = (Map<String, Object>)oAuth2AuthenticationDetails.getDecodedDetails();

    System.out.println( "My custom claim value: " + decodedDetails.get("MyClaim") );
}  

答案 2