【问题标题】:How can I access custom claims added to token using jdbc token store in authorization server in resource server?如何使用资源服务器的授权服务器中的 jdbc 令牌存储访问添加到令牌的自定义声明?
【发布时间】:2019-12-01 20:19:21
【问题描述】:

我已经使用 TokenEnhancer 在令牌中添加了自定义声明,我需要一些自定义声明在 Principal 和/或身份验证对象中可用。

我使用的是 JdbcTokenStore 而不是 JwtTokenStore。

我浏览了一些论坛和文章,但大多数都在谈论 JwtTokenStore 而不是 JdbcTokenStore。

public class AuthTokenEnhancer implements TokenEnhancer {

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {

        Map<String, Object> additionalInfo = new HashMap<>();
        additionalInfo.put("claim1", "claimVal");
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
        return accessToken;
    }

}

【问题讨论】:

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


    【解决方案1】:

    你的问题里面有答案。

    JWT 用于安全地表示两方之间的声明。没有 JWT,就没有索赔问题。

    这意味着您如何将声明添加到普通令牌中并期望它被资源服务器读取。此令牌增强器将向客户端提供附加信息,并且不会存储到任何数据库中,因此资源服务器无法知道它。

    对于您的情况,最简单的解决方案是使用 JWT。但如果它是敏感信息,也许您应该将其存储在数据库中并通过 API 公开,该 API 将检查访问它的用户的权限。

    【讨论】:

    • 我知道 JWT 自定义声明。我希望在使用 JdbcTokneStore 时实现。可以通过覆盖 ResourceServerConfigurerAdapter 的 configure(ResourceServerSecurityConfigurer resources) 并为其提供 tokenService 来完成。
    • 是的。您可以通过这种方式选择 tokenStore。但是,当您切换到 JWT 时,它不会存储到 OAUTH_ACCESS_TOKEN 表中。它是动态创建的,从不存储。这就是您不能简单地在注销时使 JWT 无效的原因。这就是建议创建一个在不到一个小时内过期的 JWT 访问令牌的原因。
    【解决方案2】:

    基本上你可以:

    1. 在 AuthorizationServer:提供您的自定义 TokenEnhancer 实现并通过AuthorizationServerConfigurer进行配置
    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.tokenEnhancer(tokenEnhancer());
        }
    
        @Bean
        public TokenEnhancer tokenEnhancer() {
            return new TestTokenEnhancer();
        }
    
    }
    
    1. 在 ResourceServer:扩展 DefaultUserAuthenticationConverter 并覆盖 extractAuthentication,您可以在其中读取来自 Map 的自定义声明并将其添加到 Authentication(或您自己的扩展)。
    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
        @Autowired
        RemoteTokenServices tokenServices;
    
        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
            resources.tokenServices(testTokenServices());
        }
    
        private ResourceServerTokenServices testTokenServices() {
            tokenServices.setAccessTokenConverter(testAccessTokenConverter());
            return tokenServices;
        }
    
        private AccessTokenConverter testAccessTokenConverter() {
            DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
            accessTokenConverter.setUserTokenConverter(testUserTokenConverter());
            return accessTokenConverter;
        }
    
        /**
         * Retrieve additional claims that were set in the TokenEnhancer of the Authorization server during Oauth token creation.
         */
        private UserAuthenticationConverter testUserTokenConverter() {
    
            return new DefaultUserAuthenticationConverter() {
    
                @Override
                public Authentication extractAuthentication(Map<String, ?> map) {
                    Authentication authentication = super.extractAuthentication(map);
    
                    if (authentication != null) {
                        authentication = new TestAuthenticationToken(authentication.getPrincipal(),
                                authentication.getCredentials(), authentication.getAuthorities(),
                                (String) map.get("testKey"));
                    }
    
                    return authentication;
                }
            };
    
        }
    
    }
    

    This thread包含相关解决方案。

    不要忘记在开发迭代期间从数据库(表oauth_access_token)中删除令牌!否则,您可能会得到一个“旧”(未过期)令牌,但不能反映您当前的自定义声明。

    【讨论】:

      猜你喜欢
      • 2017-08-28
      • 2022-08-21
      • 1970-01-01
      • 2022-10-23
      • 1970-01-01
      • 2022-11-04
      • 2019-05-27
      • 2020-12-10
      • 1970-01-01
      相关资源
      最近更新 更多