Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在刷新令牌-Spring OAuth2 java配置上未找到AuthenticationProvider_Java_Spring_Authentication_Oauth_Spring Boot - Fatal编程技术网

在刷新令牌-Spring OAuth2 java配置上未找到AuthenticationProvider

在刷新令牌-Spring OAuth2 java配置上未找到AuthenticationProvider,java,spring,authentication,oauth,spring-boot,Java,Spring,Authentication,Oauth,Spring Boot,我有一个SpringBoot项目,其中配置了一个SpringOAuth2身份验证过程,该过程部分工作。我可以进行身份验证,但当我尝试获取刷新令牌时,会出现异常 OAuth配置: @Configuration public class OAuth2ServerConfiguration { private static final String RESOURCE_ID = "xxx"; @Configuration @EnableResourceServer p

我有一个SpringBoot项目,其中配置了一个SpringOAuth2身份验证过程,该过程部分工作。我可以进行身份验证,但当我尝试获取刷新令牌时,会出现异常

OAuth配置:

@Configuration
public class OAuth2ServerConfiguration {

    private static final String RESOURCE_ID = "xxx";

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            resources.resourceId(RESOURCE_ID);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
            .authorizeRequests()
            .antMatchers("/api/**").authenticated();
        }
    }

    @Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

        @Value("${clientDetailsService.clientName}")
        private String clientName;

        @Value("${clientDetailsService.clientSecret}")
        private String clientSecret;

        @Autowired
        @Qualifier("authenticationManager")
        private AuthenticationManager authenticationManager;

        @Autowired
        private ClientDetailsService clientDetailsService;

        @Autowired
        @Qualifier("tokenServices")
        private AuthorizationServerTokenServices tokenServices;

        @Autowired
        @Qualifier("codeServices")
        private AuthorizationCodeServices codeServices;

        @Autowired
        @Qualifier("requestFactory")
        private OAuth2RequestFactory requestFactory;

        @Autowired
        @Qualifier("tokenGranter")
        private TokenGranter tokenGranter;

        private final TokenStore tokenStore = new InMemoryTokenStore();

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.setClientDetailsService(clientDetailsService);
            endpoints.tokenServices(tokenServices)
                        .tokenStore(tokenStore)
                        .authorizationCodeServices(codeServices)
                        .authenticationManager(authenticationManager)
                        .requestFactory(requestFactory)
                        .tokenGranter(tokenGranter);
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.withClientDetails(clientDetailsService);
        }


        @Bean(name = "tokenGranter")
        @Primary
        public TokenGranter tokenGranter() {
            final List<TokenGranter> tokenGranters = new ArrayList<TokenGranter>();

            tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, codeServices, clientDetailsService, requestFactory));
            tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetailsService, requestFactory));
            tokenGranters.add(new ImplicitTokenGranter(tokenServices, clientDetailsService, requestFactory));
            tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetailsService, requestFactory));
            tokenGranters.add(new CustomTokenGranter(authenticationManager, tokenServices, clientDetailsService, requestFactory));

            return new CompositeTokenGranter(tokenGranters);
        }

        @Bean
        @Primary
        public ClientDetailsService clientDetailsService(){
            final InMemoryClientDetailsServiceBuilder builder = new InMemoryClientDetailsServiceBuilder();
            builder.withClient(clientName)
                    .authorizedGrantTypes("password", "refresh_token")
                    .authorities("USER")
                    .scopes("read", "write")
                    .resourceIds(RESOURCE_ID)
                    .secret(clientSecret);

            try {
                return builder.build();
            } catch (final Exception e) {
                e.printStackTrace();
            }

            return null;

        }

        @Bean(name = "tokenServices")
        @Primary
        public AuthorizationServerTokenServices tokenServices() {
            final DefaultTokenServices tokenServices = new DefaultTokenServices();
            tokenServices.setSupportRefreshToken(true);
            tokenServices.setClientDetailsService(clientDetailsService);
            tokenServices.setTokenStore(tokenStore);
            tokenServices.setAuthenticationManager(authenticationManager);
            return tokenServices;
        }

        @Bean(name = "requestFactory")
        @Primary
        public OAuth2RequestFactory requestFactory() {
            return new DefaultOAuth2RequestFactory(clientDetailsService);
        }

        @Bean(name = "codeServices")
        @Primary
        public AuthorizationCodeServices authorizationCodeServices() {
            return new InMemoryAuthorizationCodeServices();
        }
    }
@配置
公共类OAuth2Server配置{
私有静态最终字符串资源\u ID=“xxx”;
@配置
@EnableResourceServer
受保护的静态类ResourceServerConfiguration扩展了ResourceServerConfigurerAdapter{
@凌驾
public void配置(ResourceServerSecurityConfigure资源){
resources.resourceId(RESOURCE\u ID);
}
@凌驾
public void configure(HttpSecurity http)引发异常{
http
.授权请求()
.antMatchers(“/api/**”).authenticated();
}
}
@配置
@EnableAuthorizationServer
受保护的静态类AuthorizationServerConfiguration扩展AuthorizationServerConfigurerAdapter{
@值(${clientDetailsService.clientName}”)
私有字符串clientName;
@值(${clientDetailsService.clientSecret}”)
私有字符串clientSecret;
@自动连线
@限定符(“authenticationManager”)
私人AuthenticationManager AuthenticationManager;
@自动连线
私有客户端详细信息服务客户端详细信息服务;
@自动连线
@限定符(“令牌服务”)
私有授权服务器令牌服务令牌服务;
@自动连线
@限定符(“代码服务”)
私人授权代码服务代码服务;
@自动连线
@限定符(“请求工厂”)
私有OAuth2RequestFactory请求工厂;
@自动连线
@限定符(“令牌格兰特”)
私人代币授予人代币授予人;
私有最终TokenStore TokenStore=新的InMemoryTokenStore();
@凌驾
public void configure(AuthorizationServerEndpointsConfigurer端点)引发异常{
setClientDetailsService(clientDetailsService);
端点.令牌服务(令牌服务)
.tokenStore(tokenStore)
.授权代码服务(代码服务)
.authenticationManager(authenticationManager)
.requestFactory(requestFactory)
.tokenGranter(tokenGranter);
}
@凌驾
公共无效配置(ClientDetailsServiceConfigurer客户端)引发异常{
客户端。withClientDetails(clientDetailsService);
}
@Bean(name=“tokenGranter”)
@初级的
公共令牌格兰特令牌格兰特(){
最终列表tokenGranters=new ArrayList();
添加(新授权CodeTokenGranter(tokenServices、codeServices、clientDetailsService、requestFactory));
添加(新的RefreshTokenGranter(tokenServices、clientDetailsService、requestFactory));
添加(新的隐式tokenGranters(tokenServices、clientDetailsService、requestFactory));
添加(新的ClientCredentialsTokenGranter(tokenServices、clientDetailsService、requestFactory));
添加(新的CustomTokenGranter(authenticationManager、tokenServices、clientDetailsService、requestFactory));
返回新的CompositeTokenGranter(令牌Granters);
}
@豆子
@初级的
公共客户端详细信息服务客户端详细信息服务(){
final InMemoryClientDetailsServiceBuilder=新InMemoryClientDetailsServiceBuilder();
builder.withClient(客户端名称)
.authorizedGrantTypes(“密码”、“刷新令牌”)
.当局(“用户”)
.作用域(“读”、“写”)
.ResourceID(资源\u ID)
.secret(clientSecret);
试一试{
返回builder.build();
}捕获(最终异常e){
e、 printStackTrace();
}
返回null;
}
@Bean(name=“tokenServices”)
@初级的
公共授权服务器令牌服务令牌服务(){
final DefaultTokenServices tokenServices=新的DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
setClientDetailsService(clientDetailsService);
tokenServices.setTokenStore(tokenStore);
setAuthenticationManager(authenticationManager);
退货服务;
}
@Bean(name=“requestFactory”)
@初级的
公共OAuth2RequestFactory requestFactory(){
返回新的DefaultOAuth2RequestFactory(clientDetailsService);
}
@Bean(name=“codeServices”)
@初级的
公共授权CodeServices授权CodeServices(){
返回新的InMemoryAuthorizationCodeServices();
}
}
我还定义了一些自定义组件,如自定义令牌授予器、自定义身份验证提供程序等。如有必要,我将发布它们

正如我所说,身份验证流工作正常。当我发布到/oauth/token时,我得到一个令牌和一个刷新令牌,但当我尝试将我的刷新令牌交换为一个新令牌(通过使用grant\u type=refresh\u token和refresh\u token=my refresh token发布)时,我得到一个异常:

未找到org.springframework.security.web.authentication.preauthentication.PreAuthenticatedAuthenticationToken的身份验证提供程序


我在哪里设置身份验证提供程序?如何让Spring也使用我的自定义身份验证提供程序来刷新令牌?

我通过显式定义预身份验证提供程序解决了这个问题:

@Component("preAuthProvider")
public class CustomPreAuthProvider extends PreAuthenticatedAuthenticationProvider {

    @Autowired
    private AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> userService;

    public CustomPreAuthProvider(){
        super();
    }

    @PostConstruct
    public void init(){
        super.setPreAuthenticatedUserDetailsService(userService);
    }
}

我不能不同意Jesper的回答,但在我的情况下,相同的错误已被纠正:

tokenServices.setAuthenticationManager(authenticationManager) 
来自<公司
@Autowired
private AuthenticationProvider authenticationProvider;

@Autowired
@Qualifier("preAuthProvider")
private AuthenticationProvider preAuthProvider;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(authenticationProvider).authenticationProvider(preAuthProvider);
}
tokenServices.setAuthenticationManager(authenticationManager) 
@Bean
public CustomTokenServices tokenServices() {
    CustomTokenServices tokenServices = new CustomTokenServices();
    tokenServices.setTokenStore(tokenStore());
    tokenServices.setSupportRefreshToken(true);
    tokenServices.setReuseRefreshToken(false);
    tokenServices.setClientDetailsService(clientDetailsService);
    tokenServices.setAuthenticationManager(createPreAuthProvider());
    return tokenServices;
}

private ProviderManager createPreAuthProvider() {
    PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
    provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<>(userDetailsService));
    return new ProviderManager(Arrays.asList(provider));
}