如何设置PreAuthenticationAuthenticationProvider?

时间:2016-04-22 06:26:14

标签: java spring spring-security oauth-2.0

我一直在尝试让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;
    }

}

1 个答案:

答案 0 :(得分:0)

我缺少的是AuthorizationServiceTokenServicesResourceServerTokenServices。这两个接口都是由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。