自定义DefaultTokenServices bean未被使用

时间:2018-03-02 21:05:29

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

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

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

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

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

以下是该类的相关代码

DefaultTokenServices

我在网上得到了一个答案,建议在public void configure(AuthorizationServerSecurityConfigurer security)方法中设置public function hookBackOfficeHeader() { if (Tools::getValue('module_name') == $this->name) { $this->context->controller->addJquery(); $this->context->controller->addJS($this->_path . 'views/js/back.js'); } } ,但是当我这样做时,它会使用我的自定义bean,但由于某种原因,它产生的令牌不在JWT中格式,它似乎使用标记的默认简单格式。我只是不知道为什么它不使用我的自定义bean,因为在我关注它的指南中没有以这种方式声明。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

昨天我也发生了同样的事。实际上,您需要将DefaultTokenServices添加到端点。它不是JWT格式的原因是因为默认情况下不添加该格式。您需要将JWT格式bean添加到DefaultTokenServices

此外,您需要执行与AuthorizationServerEndpointsConfigurer正在执行的操作相同或更少的操作,以便在DefaultTokenServices中生成createDefaultTokenServices(),只需替换您需要的详细信息。这是您需要添加到Authorization Server配置的相关代码:

@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方法添加到Authorization Server配置的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()));
}

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