我有一个使用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,因为在我关注它的指南中没有以这种方式声明。有什么想法吗?
答案 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()));
}
这对我有用。如果您遇到任何问题,请告诉我。