我一直在尝试让OAuth 2为我的应用程序工作,但我继续遇到与配置相关的错误,特别是涉及身份验证令牌。应用程序设置为充当授权和资源服务器。我已成功将其配置为使用密码授予类型和内存中的令牌存储来发出令牌。但是,每次我尝试发送受限资源请求时,都会收到错误消息:
org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken
所以,我尝试在我的配置中设置PreAuthenticationAuthenticationProvider
:
@Autowired
private UserDetailsManager userManager;
@Bean
public AuthenticationProvider preAuthenticationAuthenticationProvider() {
PreAuthenticatedAuthenticationProvider authenticationProvider =
new PreAuthenticatedAuthenticationProvider();
UserDetailsByNameServiceWrapper userDetailsWrapper = new UserDetailsByNameServiceWrapper(userManager);
authenticationProvider.setPreAuthenticatedUserDetailsService(userDetailsWrapper);
return authenticationProvider;
}
然而,我在奇怪的地方得到NullPointerException
,例如:
java.lang.NullPointerException: null
at org.springframework.security.authentication.AccountStatusUserDetailsChecker.check(AccountStatusUserDetailsChecker.java:17) ~[spring-security-core-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]
我想知道最简单的配置是什么,以及为什么我首先需要它?是因为我有@PreAuthorize
注释吗?
以下是我设置资源服务器的方法:
@Configuration
protected static class ResourceServer extends ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore).authenticationManager(authenticationManager);
}
@Override
public void configure(HttpSecurity http) throws Exception {
//http configuration
}
}
TokenStore
只是InMemoryTokenStore
的一个实例,AuthenticationManager
以这种方式设置:
@Configuration
protected static class WebSecurity extends WebSecurityConfigurerAdapter {
@Autowired
protected UserDetailsManager userManager;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(preAuthenticationAuthenticationProvider())
.userDetailsService(userManager).passwordEncoder(PASSWORD_ENCODER);
}
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Bean
protected AuthenticationProvider preAuthenticationAuthenticationProvider() {
PreAuthenticatedAuthenticationProvider authenticationProvider =
new PreAuthenticatedAuthenticationProvider();
UserDetailsByNameServiceWrapper userDetailsWrapper = new UserDetailsByNameServiceWrapper(userManager);
authenticationProvider.setPreAuthenticatedUserDetailsService(userDetailsWrapper);
return authenticationProvider;
}
}
答案 0 :(得分:0)
我缺少的是AuthorizationServiceTokenServices
和ResourceServerTokenServices
。这两个接口都是由Spring的DefaultTokenServices
。
@Bean
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore());
tokenServices.setAuthenticationManager(authenticationManager);
return tokenServices;
}
在授权服务器配置(AuthorizationServiceConfigurerAdapter
)中,我进行了以下设置:
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenServices(tokenServices()).authenticationManager(authenticationManager);
}
在资源服务器配置(ResourceServerConfigurerAdapter
)中:
@Autowired
private DefaultTokenServices tokenServices;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenServices(tokenServices);
}
使用所有这些组件,我的应用程序无需定义任何PreAuthenticationAuthenticationProvider
bean。