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.
init-params
are automatic, with corresponding setter method.init-params
without matching setter method will be ignored.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
.
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);
WebApplicationContextUtils
in the init
method of the Filter.
ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(cfg.getServletContext());
this.bean = ctx.getBean(YourBeanType.class);
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));
});
}
}
private boolean isFilterApplied(HttpServletRequest request) {
return this.urlMatcher.stream().anyMatch(matcher -> matcher.matches(request));
}
For full implementation checkout tech.javacloud.RequestMatcherFilter
.
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