【问题标题】:Accessing a Spring OAuth 2 JWT payload inside the Resource Server controller?访问资源服务器控制器内的 Spring OAuth 2 JWT 有效负载?
【发布时间】:2018-03-02 05:12:07
【问题描述】:

我正在通过this tutorial 了解如何使用 jwt 设置 spring boot oauth。它涵盖了使用 Angular 解码 JWT 令牌,但我们如何解码它并访问资源服务器控制器内的自定义声明?

例如,使用 JJWT 可以这样做 (Based on this article):

    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,而且是受保护的。

【问题讨论】:

    标签: java spring-boot spring-security jwt spring-oauth2


    【解决方案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") );
    }  
    

    【讨论】:

    • 我查看了很多网站,但找不到路。您的解决方案就像一个魅力。谢谢!!
    • oAuth2AuthenticationDetails.getDecodedDetails(); 正在返回 null。为什么不填充这个?
    猜你喜欢
    • 2019-04-29
    • 2021-12-26
    • 2018-12-26
    • 2013-07-12
    • 2018-07-26
    • 2015-05-14
    • 2016-08-17
    • 2019-02-06
    • 2018-02-19
    相关资源
    最近更新 更多