升级到 spring-boot 1.4.1 - OAuth2 安全集成测试通过但客户端应用无法登录
Upgrading to spring-boot 1.4.1 - OAuth2 Security integration tests pass but client apps cannot log in
我刚刚将应用程序从 spring-boot 1.3.5 升级到 spring-boot 1.4.1
出于某种原因,我所有的集成测试都通过了 oauth2。测试客户端可以在maven集成测试阶段注册用户并进行操作。
然而,当我启动 API 服务器(目前还包含资源和授权服务器)时,客户端无法再获得不记名令牌。
我的 ClientDetailsService 从未在客户端登录时被调用 - 但已在
中注册
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
在应用程序启动时。
有什么想法吗?
相关代码如下:
授权服务器配置:
import javax.inject.Inject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import blablabla.api.security.ClientDetailsServiceImpl;
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Inject
private AuthenticationManager authenticationManager;
@Inject
private ClientDetailsServiceImpl clientDetailsService;
@Inject
private UserDetailsService userDetailsService;
public AuthorizationServerConfiguration() {
System.out.println("loaded");
}
// beans
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
final JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
// FIXME: Include a more secure key in the java token store
accessTokenConverter.setSigningKey("3434343434");
return accessTokenConverter;
}
@Bean
public TokenStore tokenStore() {
//return new InMemoryTokenStore();
return new JwtTokenStore(accessTokenConverter());
}
// config
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager).accessTokenConverter(accessTokenConverter());
endpoints.userDetailsService(userDetailsService);
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
}
资源服务器配置:
import javax.inject.Inject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import blablabla.security_lib.config.UserDetailsServiceImpl;
@Configuration
@EnableResourceServer
@EnableWebSecurity
@ComponentScan("blablabla.api.security")
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Inject
private UserDetailsServiceImpl userDetailsService;
@Inject
private TokenStore tokenStore;
// Beans
@Bean
public TokenStore tokenStore() {
//return new InMemoryTokenStore();
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
final JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
accessTokenConverter.setSigningKey("3434343434");
return accessTokenConverter;
}
// global security concerns
@Bean
public AuthenticationProvider authProvider() {
final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
return authProvider;
}
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authProvider());
}
@Primary
@Bean
public ResourceServerTokenServices getTokenServices () {
DefaultTokenServices services = new DefaultTokenServices();
services.setSupportRefreshToken(true);
services.setTokenStore(tokenStore);
return services;
}
// http security concerns
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll().and().csrf().disable();
/*http
.authorizeRequests().regexMatchers("^/members").anonymous()
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf()
.disable();*/
}
}
我也注意到了一些事情 - 这对某些人来说可能意味着什么。
当登录不起作用时(启动 api 并使用客户端)
向 org.springframework.security.web.access.expression.WebExpressionVoter 传递了一个集合,其中包含一个 org.springframework.security.web.access.expression.WebExpressionConfigAttribute 类型的属性,其值为
“#oauth2.throwOnError(已验证)”
当登录有效时(运行 验收测试)
向 org.springframework.security.web.access.expression.WebExpressionVoter 传递了一个集合,其中包含一个 org.springframework.security.web.access.expression.WebExpressionConfigAttribute 类型的属性,其值为
“[完全认证]”
所以这根本不是 spring-引导问题,而是从 spring-cloud Brixton.M2 升级时在我们的网关服务器中引起的某种问题将列车开往 Brixton.RELEASE。这是对一个无用问题的无用回答,所以 - 很高兴看到它从 SO 中删除。
我刚刚将应用程序从 spring-boot 1.3.5 升级到 spring-boot 1.4.1
出于某种原因,我所有的集成测试都通过了 oauth2。测试客户端可以在maven集成测试阶段注册用户并进行操作。
然而,当我启动 API 服务器(目前还包含资源和授权服务器)时,客户端无法再获得不记名令牌。
我的 ClientDetailsService 从未在客户端登录时被调用 - 但已在
中注册 @Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
在应用程序启动时。
有什么想法吗?
相关代码如下:
授权服务器配置:
import javax.inject.Inject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import blablabla.api.security.ClientDetailsServiceImpl;
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Inject
private AuthenticationManager authenticationManager;
@Inject
private ClientDetailsServiceImpl clientDetailsService;
@Inject
private UserDetailsService userDetailsService;
public AuthorizationServerConfiguration() {
System.out.println("loaded");
}
// beans
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
final JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
// FIXME: Include a more secure key in the java token store
accessTokenConverter.setSigningKey("3434343434");
return accessTokenConverter;
}
@Bean
public TokenStore tokenStore() {
//return new InMemoryTokenStore();
return new JwtTokenStore(accessTokenConverter());
}
// config
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager).accessTokenConverter(accessTokenConverter());
endpoints.userDetailsService(userDetailsService);
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
}
资源服务器配置:
import javax.inject.Inject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import blablabla.security_lib.config.UserDetailsServiceImpl;
@Configuration
@EnableResourceServer
@EnableWebSecurity
@ComponentScan("blablabla.api.security")
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Inject
private UserDetailsServiceImpl userDetailsService;
@Inject
private TokenStore tokenStore;
// Beans
@Bean
public TokenStore tokenStore() {
//return new InMemoryTokenStore();
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
final JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
accessTokenConverter.setSigningKey("3434343434");
return accessTokenConverter;
}
// global security concerns
@Bean
public AuthenticationProvider authProvider() {
final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
return authProvider;
}
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authProvider());
}
@Primary
@Bean
public ResourceServerTokenServices getTokenServices () {
DefaultTokenServices services = new DefaultTokenServices();
services.setSupportRefreshToken(true);
services.setTokenStore(tokenStore);
return services;
}
// http security concerns
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll().and().csrf().disable();
/*http
.authorizeRequests().regexMatchers("^/members").anonymous()
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf()
.disable();*/
}
}
我也注意到了一些事情 - 这对某些人来说可能意味着什么。
当登录不起作用时(启动 api 并使用客户端)
向 org.springframework.security.web.access.expression.WebExpressionVoter 传递了一个集合,其中包含一个 org.springframework.security.web.access.expression.WebExpressionConfigAttribute 类型的属性,其值为 “#oauth2.throwOnError(已验证)”
当登录有效时(运行 验收测试)
向 org.springframework.security.web.access.expression.WebExpressionVoter 传递了一个集合,其中包含一个 org.springframework.security.web.access.expression.WebExpressionConfigAttribute 类型的属性,其值为 “[完全认证]”
所以这根本不是 spring-引导问题,而是从 spring-cloud Brixton.M2 升级时在我们的网关服务器中引起的某种问题将列车开往 Brixton.RELEASE。这是对一个无用问题的无用回答,所以 - 很高兴看到它从 SO 中删除。