Java – What’s the point of Spring MVC’s DelegatingFilterProxy

javaspringspring-mvcspring-security

I see this in my Spring MVC app's web.xml:

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

I'm trying to figure out why it's there and whether it's actually needed.

I found this explanation in the Spring docs but it doesn't help me make sense of it:

It seems to suggest that this component is the "glue" between the servlets defined in web.xml and the components defined in the Spring applicationContext.xml.

7.1 DelegatingFilterProxy

When using servlet filters, you obviously need to declare them in your web.xml, or they will be ignored by the servlet container. In Spring Security, the filter classes are also Spring beans defined in the application context and thus able to take advantage of Spring's rich dependency-injection facilities and lifecycle interfaces. Spring's DelegatingFilterProxy provides the link between web.xml and the application context.

When using DelegatingFilterProxy, you will see something like this in the web.xml file:

<filter>
   <filter-name>myFilter</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
   <filter-name>myFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

Notice that the filter is actually a DelegatingFilterProxy, and not the class that will actually implement the logic of the filter. What DelegatingFilterProxy does is delegate the Filter's methods through to a bean which is obtained from the Spring application context. This enables the bean to benefit from the Spring web application context lifecycle support and configuration flexibility. The bean must implement javax.servlet.Filter and it must have the same name as that in the filter-name element. Read the Javadoc for DelegatingFilterProxy for more information

So, if I take this out of my web.xml, what will happen? My servlets won't be able to communicate with the Spring container?**

Best Answer

There's some kind of magic here, but at the end, everything is a deterministic program.

The DelegatingFilterProxy is a Filter as it was explained above, whose goal is "delegating to a Spring-managed bean that implements the Filter interface", that is, it finds a bean ("target bean" or "delegate") in your Spring application context and invokes it. How is it possible? Because this bean implements javax.servlet.Filter, its doFilter method is called.

Which bean is called? the DelegatingFilterProxy "Supports a "targetBeanName" [...], specifying the name of the target bean in the Spring application context."

As you saw in your web.xml that the bean's name is "springSecurityFilterChain".

So, in the context of a web application, a Filter instantiates a bean called "springSecurityFilterChain" in your application context and then delegate to it via the doFilter() method.

Remember, your application context is defined with ALL THE APPLICATION-CONTEXT (XML) files. For instance: applicationContext.xml AND applicationContext-security.xml.

So try to find a bean called "springSecurityFilterChain" in the latter...

...and probably you can't (for instance if you followed a tutorial or if you configured the security using Roo)

Here is the magic: there's a new element for configuring the security, something like

<http auto-config="true" use-expressions="true"> 

as it is allowed by http://www.springframework.org/schema/security/spring-security-3.0.xsd, will do the trick.

When Spring loads the application context using XML files, if it finds a element, it will try to set up the HTTP security, that is, a filter stack and protected URLs and to register the FilterChainProxy named "springSecurityFilterChain".

Alternatively, you can define the bean in the classic way, that is:

<beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">

But it's less recommended, since you need to do a lot of configuration (all the filters that you're going to use. And there are more than a dozen of them)