简体   繁体   English

如何设置PreAuthenticationAuthenticationProvider?

[英]How do I set up PreAuthenticationAuthenticationProvider?

I've been trying to get OAuth 2 working for my application but I continue running into configuration-related errors, specifically involving authentication tokens. 我一直在尝试让OAuth 2为我的应用程序工作,但我继续遇到与配置相关的错误,特别是涉及身份验证令牌。 The application is set up to act as both authorization and resource server. 应用程序设置为充当授权和资源服务器。 I've successfully configured it to issue tokens using password grant type, with an in-memory token store. 我已成功将其配置为使用密码授予类型和内存中的令牌存储来发出令牌。 However, every time I try to send requests for restricted resources, I get errors saying: 但是,每次我尝试发送受限资源请求时,都会收到错误消息:

org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken

So, I tried setting up a PreAuthenticationAuthenticationProvider in my configuration: 所以,我尝试在我的配置中设置PreAuthenticationAuthenticationProvider

@Autowired
private UserDetailsManager userManager;

@Bean
public AuthenticationProvider preAuthenticationAuthenticationProvider() {
    PreAuthenticatedAuthenticationProvider authenticationProvider =
        new PreAuthenticatedAuthenticationProvider();
    UserDetailsByNameServiceWrapper userDetailsWrapper = new UserDetailsByNameServiceWrapper(userManager);
    authenticationProvider.setPreAuthenticatedUserDetailsService(userDetailsWrapper);
    return authenticationProvider;
}

However, I'm getting NullPointerException in weird places, like: 但是,我在奇怪的地方得到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]

I'm wondering what the simplest configuration for this is, and why I need it in the first place? 我想知道最简单的配置是什么,以及为什么我首先需要它? Is it because I have @PreAuthorize annotations? 是因为我有@PreAuthorize注释吗?

Here's how I set up the resource server: 以下是我设置资源服务器的方法:

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

}

The TokenStore is just an instance of InMemoryTokenStore and AuthenticationManager is set up this way: 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;
    }

}

What I was missing are AuthorizationServiceTokenServices and ResourceServerTokenServices . 我缺少的是AuthorizationServiceTokenServicesResourceServerTokenServices Both these interfaces are implmented by Spring's DefaultTokenServices . 这两个接口都是由Spring的DefaultTokenServices

@Bean
public DefaultTokenServices tokenServices() {
    DefaultTokenServices tokenServices = new DefaultTokenServices();
    tokenServices.setTokenStore(tokenStore());
    tokenServices.setAuthenticationManager(authenticationManager);
    return tokenServices;
}

In the authorization server configuration ( AuthorizationServiceConfigurerAdapter ), I have the following setup: 在授权服务器配置( AuthorizationServiceConfigurerAdapter )中,我有以下设置:

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.tokenServices(tokenServices()).authenticationManager(authenticationManager);
}

In the resource server configuration ( ResourceServerConfigurerAdapter ): 在资源服务器配置( ResourceServerConfigurerAdapter )中:

@Autowired
private DefaultTokenServices tokenServices;

@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    resources.tokenServices(tokenServices);
}

With all these components, my app works without any PreAuthenticationAuthenticationProvider bean defined. 使用所有这些组件,我的应用程序无需定义任何PreAuthenticationAuthenticationProvider bean。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM