I tried to use spring-security, and get this error.
java.lang.NullPointerException
at org.springframework.security.web.FilterChainProxy.getFilters(FilterChainPro
You are creating a FilterChainProxy
bean with an null
filter list in your XML configuration and this bean is than used in the web.xml by DelegatingFilterProxy
. FilterChainProxy#getFilters
tries to iterate over the null
list and naturally fails with a NullPointerException
.
The root of the problem is, that you cannot mix Java configuration and traditional XML configuration like this. The Java configuration creates a separate FilterChainProxy
bean that has nothing to do with the bean configured via XML.
I have figured out what is going on here, but I think you are much better off sticking to only Java Config or XML config rather than mixing and matching them in relation to integration Spring MVC and Security.
In XML Configuration, The springSecurityFilterChain is created by the http
namespace in your spring-security.xml. Refer here. Since you have switched to java config there is no springSecurityFilterChain created which is exactly what the application is complaining about.
To Create the springSecurityFilterChain in you need to do the following 2 steps.
Step 1
Remove the following from your web.xml
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Step 2
Create a AbstractSecurityWebApplicationInitializer
which will create the springsecurityfilterchain for you.
public class SpringSecurityInitializer extends
AbstractSecurityWebApplicationInitializer {
}
Now AbstractSecurityWebApplicationInitializer
documentation says that
When used with AbstractSecurityWebApplicationInitializer(), this class is typically used in addition to a subclass of AbstractContextLoaderInitializer.
So now you have to create AbstractContextLoaderInitializer yourself. For this I have made 2 changes
Step 1 :- Remove below from web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
Step 2:- Create a Class SpringAnnotationWebInitializer
and ApplicationContextSpring
which will have the following content
public class SpringAnnotationWebInitializer extends
AbstractContextLoaderInitializer {
@Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.register(ApplicationContextSpring.class);
return applicationContext;
}
}
and ApplicationContextSpring
will be
@Configuration
@ImportResource("classpath:applicationContext.xml")
@Import(SecurityConfig.class)
public class ApplicationContextSpring {
}
Like I said, you are much better of creating either java or xml config.