'springSecurityFilterChain'抛出java.lang.IllegalArgumentException:提供程序列表不能包含空值



我正在尝试构建一个Spring Boot应用程序,这是一个能够加载web界面并创建、检索、更新和删除实体(例如学校的学生(的简单示例,其中一些操作仅限于某些用户(因此我使用的是Spring Security(。它运行良好,但在进行了Checkstyle和PMD建议的一些更改后,它不再运行,而是抛出以下堆栈跟踪:

2020-08-08 18:19:48.608 ERROR 30203 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: providers list cannot contain null values
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:483) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1336) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1176) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:311) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) ~[spring-context-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) ~[spring-context-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) [spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) [spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.2.RELEASE.jar:2.3.2.RELEASE]
at com.example.demo.DemoApplication.main(DemoApplication.java:19) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_252]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_252]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_252]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_252]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.3.2.RELEASE.jar:2.3.2.RELEASE]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: providers list cannot contain null values
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:650) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
... 27 common frames omitted
Caused by: java.lang.IllegalArgumentException: providers list cannot contain null values
at org.springframework.security.authentication.ProviderManager.checkState(ProviderManager.java:149) ~[spring-security-core-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.authentication.ProviderManager.<init>(ProviderManager.java:133) ~[spring-security-core-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder.performBuild(AuthenticationManagerBuilder.java:236) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder.performBuild(AuthenticationManagerBuilder.java:50) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:333) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:41) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration.getAuthenticationManager(AuthenticationConfiguration.java:118) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.authenticationManager(WebSecurityConfigurerAdapter.java:269) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:202) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:322) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:94) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at com.example.demo.config.SpringSecConfig$$EnhancerBySpringCGLIB$$76cdcc3a.init(<generated>) ~[classes/:na]
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:370) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:324) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:41) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:104) ~[spring-security-config-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_252]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_252]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_252]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_252]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
... 28 common frames omitted

这些变化就像在可能的情况下使参数和变量成为最终值,这通常不会导致这种情况。我自己在堆栈跟踪中引用的唯一类是main类和Spring Security配置类:

SpringSecConfig.java

package com.example.demo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* Spring Security configuration class.
* @author Me
*
*/
@Configuration
public class SpringSecConfig extends WebSecurityConfigurerAdapter { //NOPMD
/**
* The authentication provider.
*/
private AuthenticationProvider provider; //NOPMD
/**
* Mutator for the authentication provider.
* @param provider The authentication provider.
*/
@Autowired
@Qualifier("daoAuthenticationProvider")
public void setProvider(final AuthenticationProvider provider) {
this.provider = provider;
}
/**
* Creates a new BCrypt-based password encoder.
* @return The password encoder.
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* Creates a DaoAuthenticationProvider with BCrypt-based password encryption 
* that uses the provided service.
* @param service The service to load user data.
* @return An AuthenticationProvider.
*/
@Bean("daoAuthenticationProvider")
public AuthenticationProvider daoAuthenticationProvider(final UserDetailsService service) {
final DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(new BCryptPasswordEncoder());
provider.setUserDetailsService(service);
return provider;
}
/**
* Assigns an authentication provider to the Authentication Manager Builder.
* @param authMB The Authentication Manager Builder.
*/
@Autowired
public void configureAuthManager(final AuthenticationManagerBuilder authMB) {
authMB.authenticationProvider(provider);
}
@Override
protected void configure(final HttpSecurity httpSecurity) throws Exception {
httpSecurity //NOPMD
.authorizeRequests()
.requestMatchers(PathRequest.toStaticResources() //NOPMD
.atCommonLocations())
.permitAll()
.antMatchers("/**", "/people", "/person/show/*", "/console/*", "/h2-console/**")
.permitAll()
.anyRequest()
.authenticated()
.and().formLogin().loginPage("/login")
.permitAll()
.and().logout()
.permitAll();
httpSecurity.csrf().disable(); //NOPMD
httpSecurity.headers().frameOptions().disable(); //NOPMD
}
}

DemoApplication.java

package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Point of entry of the application.
* @author Me
*
*/
@SpringBootApplication
public class DemoApplication { //NOPMD
/**
* Main method.
* @param args The arguments.
*/
public static void main(final String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

这里有一个相关但尚未回答的问题。

我知道org.springframework.security.authentication.ProviderManager.checkState((中检查的提供者列表包含一个null值,这就是问题的原因。但我不明白为什么它包含那个空值。有什么想法吗?提前谢谢。

我认为在调用configureAuthManager之前,您的onAuthenticationProvider还没有准备好,请尝试使用(未测试(

@Autowired
public void configureAuthManager(final AuthenticationManagerBuilder authMB, @Qualifier("daoAuthenticationProvider") AuthenticationProvider provider) {
authMB.authenticationProvider(provider);
}

相关内容

最新更新