Spring Security | What Is Spring Security? | Without web.xml
If the application server supports Servlet 3.0 or later, you can use Spring Security without web.xml.
.
├── build.gradle
└── src
└── main
├── java
│ └── sample
│ └── spring
│ └── security
│ ├── MySpringSecurityConfig.java
│ └── MySpringSecurityInitializer.java
└── webapp
└── index.jsp
src/main/java/sample/spring/security/MySpringSecurityInitializer.java
package sample.spring.security;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class MySpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
public MySpringSecurityInitializer() {
super(MySpringSecurityConfig.class);
}
}
MySpringSecurityConfig.java and index.jsp are unchanged and omitted.
Remove web.xml and add MySpringSecurityInitializer. It extends AbstractSecurityWebApplicationInitializer and passes the Java configuration class to the parent constructor. This makes the previous web.xml settings unnecessary.
Structure
This feature uses APIs added in Servlet 3.0.
ServletContainerInitializer
AbstractSecurityWebApplicationInitializer implements WebApplicationInitializer. Its Javadoc explains that implementations are detected automatically by SpringServletContainerInitializer, which Servlet 3.0 containers bootstrap automatically.
WebApplicationInitializer.java
/**
* ...
*
* <p>Implementations of this SPI will be detected automatically by {@link
* SpringServletContainerInitializer}, which itself is bootstrapped automatically
* by any Servlet 3.0 container. See {@linkplain SpringServletContainerInitializer its
* Javadoc} for details on this bootstrapping mechanism.
* ...
*/
public interface WebApplicationInitializer {
SpringServletContainerInitializer implements ServletContainerInitializer and is annotated with @HandlesTypes.
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
...
When the servlet container starts, it invokes onStartup(Set<Class<?>>, ServletContext). The container discovers classes related to the type specified by @HandlesTypes and passes them as the first argument. SpringServletContainerInitializer therefore receives implementations of WebApplicationInitializer, creates instances, and invokes onStartup(ServletContext).
AbstractSecurityWebApplicationInitializer
AbstractSecurityWebApplicationInitializer.onStartup(ServletContext) performs the settings previously defined in web.xml.
public abstract class AbstractSecurityWebApplicationInitializer
implements WebApplicationInitializer {
public static final String DEFAULT_FILTER_NAME = "springSecurityFilterChain";
public final void onStartup(ServletContext servletContext) throws ServletException {
beforeSpringSecurityFilterChain(servletContext);
if (this.configurationClasses != null) {
AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext();
rootAppContext.register(this.configurationClasses);
servletContext.addListener(new ContextLoaderListener(rootAppContext));
}
if (enableHttpSessionEventPublisher()) {
servletContext.addListener(
"org.springframework.security.web.session.HttpSessionEventPublisher");
}
servletContext.setSessionTrackingModes(getSessionTrackingModes());
insertSpringSecurityFilterChain(servletContext);
afterSpringSecurityFilterChain(servletContext);
}
private void insertSpringSecurityFilterChain(ServletContext servletContext) {
String filterName = DEFAULT_FILTER_NAME;
DelegatingFilterProxy springSecurityFilterChain = new DelegatingFilterProxy(filterName);
String contextAttribute = getWebApplicationContextAttribute();
if (contextAttribute != null) {
springSecurityFilterChain.setContextAttribute(contextAttribute);
}
registerFilter(servletContext, true, filterName, springSecurityFilterChain);
}
}
The key point is that the implementation now performs the configuration previously written in web.xml.