I am trying to implement Spring-Security 4 into my Spring MVC web and rest app. I added 2 classes to enable Spring Security the java config way. I still want to hold onto my web.xml and not change the entire project to use java config. As soon as I do that, I get the following error:
29-May-2015 08:47:12.826 SEVERE [localhost-startStop-1]
org.apache.catalina.core.StandardContext.filterStart Exception starting
filter springSecurityFilterChain
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean
named 'springSecurityFilterChain' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.
getBeanDefinition(DefaultListableBeanFactory.java:687)
As you can see, it says that the springSecurityFilterChain cannot be recognized. This is of course supposed to be enabled by the @EnableWebSecurity as you see below:
Classes used for Spring Security:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("abc").password("123456").roles("USER");
auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
auth.inMemoryAuthentication().withUser("dba").password("123456").roles("DBA");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.antMatchers("/dba/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')")
.and().formLogin();
}
}
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
//do nothing
}
The weird thing is if I add the springSecurityFilterChain to my web.xml, at runtime it complains and says there is a duplicate springSecurityFilterChain. I noticed that ultimately in the Java config, they do this:
public class MvcWebApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SecurityConfig.class };
}
Where they register the SecurityConfig with the Java config for the MvcWebApp. This basically makes it part of the servlet context I believe.
All in all, how can I have my springSecurityFilterChain recognized? Do I need to register my SecurityConfig class in web.xml or the existing application context?
I think this may be the first problem area:
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
}
The spring docs say:
Instead, we should register Spring Security with the existing ApplicationContext. For example, if we were using Spring MVC our SecurityWebApplicationInitializer.
Can this mean in my case, I can take SecurityConfig and should make it a bean? Or is it not already a bean because it is dicoverable through @Configuration?
How can I make SecurityConfig recognized via XML while using the new Java config as well?
Thanks to ArunM, I revisited my issue and now have an XML and Java config combination. Spring MVC and the web app does use web.xml and default-servlet.xml PLUS a java config app class that imports Spring Security.
I use the @Import annotation to import the Spring Security SecurityConfig class.
I also do my contextConfigLocation scanning for all my context files via annotation: @ImportResource.
The trick was not to load SecurityConfig via the contextConfigLocation BUT create an AppConfig class that sets up the app context by including everything in it together.
Add the following line in your spring-context.xml:
and then can add the bean definition for the security config.
Assuming what you want is to get Spring Security Java Config working with only 2 classes
SecurityConfig
andSecurityWebApplicationInitializer
, you need to do the following to get it working. Please note that I am assuming that your spring mvc configuration is still XML. Please note thatcom.mkyong.web.config
package will have theSecurityConfig
class. This will ensure that the web context will have your security configuration available.Web.xml as follows