What is the recommended way to add Spring Security to a web application that is using Spring\'s new WebApplicationInitializer
interface instead of the web.xml file?
After a bit of work, I've discovered that it's actually quite simple:
public class Initialiser extends AbstractAnnotationConfigDispatcherServletInitializer implements WebApplicationInitializer {
@Override
protected Class< ? >[] getRootConfigClasses() {
return new Class[] { RootConfig.class };
}
@Override
protected Class< ? >[] getServletConfigClasses() {
return new Class[] { WebAppConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new DelegatingFilterProxy("springSecurityFilterChain") };
}
}
The most important thing, though, is that you must have a root context (e.g. RootConfig
in this case), and that must contain a reference to all the spring security information.
Thus, my RootConfig
class:
@ImportResource("classpath:spring/securityContext.xml")
@ComponentScan({ "com.example.authentication", "com.example.config" })
@Configuration
public class RootConfig {
@Bean
public DatabaseService databaseService() {
return new DefaultDatabaseService();
}
@Bean
public ExceptionMappingAuthenticationFailureHandler authExceptionMapping() {
final ExceptionMappingAuthenticationFailureHandler emafh = new ExceptionMappingAuthenticationFailureHandler();
emafh.setDefaultFailureUrl("/loginFailed");
final Map mappings = new HashMap<>();
mappings.put(CredentialsExpiredException.class.getCanonicalName(), "/change_password");
emafh.setExceptionMappings(mappings);
return emafh;
}
}
And spring/securityContext.xml
:
I could not get it to work if I merged the RootConfig
and WebAppConfig
classes into just WebAppConfig
and had the following:
@Override
protected Class< ? >[] getRootConfigClasses() {
return null;
}
@Override
protected Class< ? >[] getServletConfigClasses() {
return new Class[] { WebAppConfig.class };
}