首页 > 解决方案 > 如何使用资源服务器的授权服务器中的 jdbc 令牌存储访问添加到令牌的自定义声明?

问题描述

我已经使用 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;
    }

}

标签: springspring-bootspring-security-oauth2

解决方案


基本上你可以:

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

    }

}

该线程包含相关的解决方案。

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


推荐阅读