How to exclude a URL from a Filter

By default, filters doesn’t support excluding a specific URL pattern, whenever you define a URL pattern for a filter then any request matching this pattern is handled by the filter without exceptions.

The simplest way for excluding URLs from a filter is to map your filter to a very specific pattern. This is feasible when done in early development stages, however it could be a cumbersome process if you modify the URL pattern of an existing filter in a production environment as you have to remap all the existing servlet URLs to achieve your purpose.

In this tutorial, we show how to programatically add an exclude functionality to an existing filter.

1- Custom Filter

A custom filter is a filter which you can control. i.e. you have all the rights to modify its source code.

Suppose we have an existing web application which authenticates user requests through LDAP. All the servlet requests pass through LDAPAuthenticationFilter which is mapped to /* as the following:

Our filter simply authenticates the request and calls chain.doFilter() afterwards:

Now, suppose we want to create a servlet which requires a simple database authentication and needs not to pass through LDAP. The first thing we think of it to create a new filter and map it to the specific URL pattern of the new servlet.

So we create a new filter named as DatabaseAuthenticationFilter which simply authenticates the request through database and calls chain.doFilter() afterwards:

We define our filter under web.xml to handle only specific URLs starting with /DatabaseAuthenticatedServlet:

The problem here is that requests like /DatabaseAuthenticatedServlet would also match the root URL pattern “/*”, i.e. our request would pass through 2 authentication processes: LDAP and Database, the ordering depends on which filter is defined first under web.xml.

In order to solve this, we need to modify LDAPAuthenticationFilter so that it excludes URLs starting with /DatabaseAuthenticatedServlet. What people normally do is to statically check over the servlet URL of the request inside doFilter() method and simply bypass the authentication process when found.

Here we go a step further and implement a more dynamic solution which allows us to manage the excluded URLs through web.xml.

Following are the steps for adding the exclude feature to LDAPAuthenticationFilter:

  • Add a new field called excludedUrls of type List<String>:
  • Inside init() method, read a configuration attribute called excludedUrls using FilterConfig, the attribute is supposed to be comma-separated so that we exclude as much URLs as we need.
  • Modify doFilter() in order to checks if the requested URL belongs to the list of predefined excluded URLs, if so then just forward the request to the next filter or servlet in the chain, otherwise do your authentication logic.
  • Now inside web.xml, you can control which URL to exclude from LDAP authentication without any single code change:

This is how LDAPAuthenticationFilter looks like after adding the exclude functionality:

2- Third-party Filter

The third-party filters are the filters which you can’t control. i.e. you can’t modify their source code.

In this section, we alter our example a bit and use CAS authentication instead of LDAP. This is how we define our CAS authentication filter in web.xml:

CAS authentication is done through a third-party library, now in order to support database authentication we can’t modify the source code of CAS as we did in the previous example with LDAP.

The solution for excluding URLs from a third-party filter is to wrap it with a new custom filter which just adds the exclude functionality and delegates the filter logic to the wrapped class.

Following are the steps for adding exclude functionality to CAS authentication:

  • Create a new filter called CASCustomAuthenticationFilter as the following:

    Our custom filter wraps the CAS authentication filter through composition, its main purpose is to just manage which URLs to be authenticated through CAS , while we didn’t touch the CAS authentication procedure.
  • In web.xml, we change the filter definition to use CASCustomAuthenticationFilter instead of the default CAS implementation:

That’s it, please leave your thoughts in the comments section below.

 

husseinterek

Founder of programmergate.com, I have a passion in software engineering and everything related to java environment.

You may also like...

Leave a Reply

Be the First to Comment!

avatar