Introduction

Filter: javax.servlet.Filter is an object that will be used for filtering on the request or response or both.

javax.servlet.Filter is called by the container each time a request and response are passed through the filter.

GenericFilterBean: org.springframework.web.filter.GenericFilterBean is a implementation of javax.servlet.Filter, which treats config parameter init-params as bean properties.

Note:
1. javax.servlet.Filter will not run in the Spring Container. Where as org.springframework.web.filter.GenericFilterBean will run in the Spring Container.
2. In javax.servlet.Filter beans cannot be Autowired, it has to done explicitly to inject the beans.
3. javax.servlet.Filter has to be wrapped in org.springframework.boot.web.servlet.FilterRegistrationBean.
4. URL Patterns for the subclass of the org.springframework.web.filter.GenericFilterBean does not work even if the filter is registered with org.springframework.boot.web.servlet.FilterRegistrationBean.
5. URL Patterns for the subclass of the org.springframework.web.filter.OncePerRequestFilter does not work even if the filter is registered with org.springframework.boot.web.servlet.FilterRegistrationBean.

Filters in Spring

There are 2 ways to implement filters in Spring
Option 1: Implement a javax.servlet.Filter
To remember
* Filter class will not be running in the Spring Container.
* Filter class property will not be @Autowired with beans from Spring Container.

To use Spring Beans
* Add the Filter class to org.springframework.boot.web.servlet.FilterRegistrationBean if using the filter in Spring Boot.
* Using org.springframework.web.context.support.SpringBeanAutowiringSupport in the init method of the Filter.

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

In this option using the spring beans is up to the developer to instruct Spring Container process it.

Check out RequestFilter in the code example and application class for configuration.

Option 2: Implement a GenericFilterBean
To remember
* @Autowired beans are injected by the Spring Container.
* Life cycle of the bean is handled by the Spring Container.
* By default the filter is called on all the requests /*. To handle a specific URLs configure the <filter> in web.xml file.

Problem Statement:
* URL patterns can be changed without code changes.
* URL patterns should support the Ant Patterns.
* Filter is added as part of the Spring Security Filter Chain.

Solution:
* @Value to inject the URL patterns from the property file.
* Use a org.springframework.security.web.util.matcher.AntPathRequestMatcher.

@Value("#{'${request.matcher}'.split(',')}")
private void setUrlMatcher(List<String> requestMatcher) {
	if(requestMatcher != null) {
		this.urlMatcher = new ArrayList<>();
		requestMatcher.forEach(request -> {
			this.urlMatcher.add(new AntPathRequestMatcher(request));
		});
	}
}

For full implementation checkout tech.javacloud.RequestMatcherFilter.

Code

Request Matcher Sample

In the sample application, there are 3 end points.
1. /hello --> Not secure
2. /secure --> Secure requires authentication (admin/admin)
3. /hello/second --> Not Secure


Published on 14 January 2022