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.