【问题标题】:Custom DefaultTokenServices bean not being used未使用自定义 DefaultTokenServices bean
【发布时间】:2018-08-11 03:45:53
【问题描述】:

我有一个使用 JWT 和 OAuth2 的 Spring Boot Rest API

Spring Boot 1.5.10 使用 spring security starter 和 oauth2 和 jwt 模块的默认版本。

在我的授权服务器配置中,我根据本指南在此处 http://www.baeldung.com/spring-security-oauth-jwt 声明自定义 DefaultTokenServices

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private DataSource dataSource;

    @Value("${tokenSigningKey:sdf8234kjdhgD}")
    private String tokenSigningKey;

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        CustomJwtAccessTokenConverter accessTokenConverter = new CustomJwtAccessTokenConverter();
        accessTokenConverter.setSigningKey(tokenSigningKey);
        return accessTokenConverter;
    }

    @Bean
    public TokenStore tokenStore() {
        return new CustomJwtJdbcTokenStore(accessTokenConverter(), dataSource);
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }

    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomAccessTokenEnhancer();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new CustomPasswordEncoder();
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource).passwordEncoder(passwordEncoder());
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));
        endpoints
                .tokenStore(tokenStore())
                .tokenEnhancer(tokenEnhancerChain)
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.passwordEncoder(passwordEncoder());
        security.checkTokenAccess("isAuthenticated()");
    }

}

然而,实际使用的DefaultTokenServices 是在AuthorizationServerEndpointsConfigurer 的幕后构建的

这是该类的相关代码

public AuthorizationServerTokenServices getDefaultAuthorizationServerTokenServices() {
        if (defaultTokenServices != null) {
            return defaultTokenServices;
        }
        this.defaultTokenServices = createDefaultTokenServices();
        return this.defaultTokenServices;
    }

    private DefaultTokenServices createDefaultTokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setTokenStore(tokenStore());
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setReuseRefreshToken(reuseRefreshToken);
        tokenServices.setClientDetailsService(clientDetailsService());
        tokenServices.setTokenEnhancer(tokenEnhancer());
        addUserDetailsService(tokenServices, this.userDetailsService);
        return tokenServices;
    }

我在网上遇到了一个答案,建议在 public void configure(AuthorizationServerSecurityConfigurer security) 方法中设置 DefaultTokenServices,但是当我这样做时,它确实使用了我的自定义 bean,但由于某种原因,它产生的令牌不是 JWT 格式,它似乎使用令牌的默认简单格式。我只是不知道为什么它不使用我的自定义 bean,因为在我遵循的指南中,它没有以这种方式声明。有什么想法吗?

【问题讨论】:

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


    【解决方案1】:

    昨天我也遇到了同样的情况。实际上,您需要将DefaultTokenServices 添加到端点。它之所以没有以 JWT 格式出现,是因为默认情况下没有添加该格式。您需要将 JWT 格式 bean 添加到您的 DefaultTokenServices

    此外,您需要执行与 AuthorizationServerEndpointsConfigurer 所做的或多或少相同的操作,以在 createDefaultTokenServices() 中生成 DefaultTokenServices,只需替换您需要的详细信息。这是您需要添加到授权服务器配置的相关代码:

    @Bean
    @Primary
    public DefaultTokenServices tokenServices(TokenEnhancerChain tokenEnhancerChain, ClientDetailsService clientDetailsService) {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        defaultTokenServices.setTokenEnhancer(tokenEnhancerChain);
        defaultTokenServices.setClientDetailsService(clientDetailsService);
        addUserDetailsService(defaultTokenServices,userDetailsService);
        return defaultTokenServices;
    }
    
    private void addUserDetailsService(DefaultTokenServices tokenServices, UserDetailsService userDetailsService) {
        if (userDetailsService != null) {
            PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
            provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken>(
                    userDetailsService));
            tokenServices
                    .setAuthenticationManager(new ProviderManager(Arrays.<AuthenticationProvider> asList(provider)));
        }
    }
    

    并将tokenServices 方法添加到您的授权服务器配置的configure 方法中:

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
            tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));
            endpoints
                    .tokenStore(tokenStore())
                    .tokenEnhancer(tokenEnhancerChain)
                    .authenticationManager(authenticationManager)
                    .userDetailsService(userDetailsService)
                    .tokenServices(tokenServices(tokenEnhancerChain,endpoints.getClientDetailsService()));
    }
    

    这对我有用。如果您遇到任何问题,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2020-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多