How to Apply Spring Boot Filter Based on Url Pattern

How to apply spring boot filter based on URL pattern?

You can add a filter like this:

@Bean
public FilterRegistrationBean someFilterRegistration() {

FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(someFilter());
registration.addUrlPatterns("/url/*");
registration.addInitParameter("paramName", "paramValue");
registration.setName("someFilter");
registration.setOrder(1);
return registration;
}

@Bean(name = "someFilter")
public Filter someFilter() {
return new SomeFilter();
}

How can i enable spring filter for a specific url?

Add multiple FilterRegistration per different url pattern

 FilterRegistration myFilter = servletContext.addFilter("myFilter ", MyFilter.class);
myFilter.addMappingForUrlPatterns(null, false, "/myservlet/myendpoint/*");
FilterRegistration myFilter2 = servletContext.addFilter("myFilter2 ", MyFilter2.class);
myFilter.addMappingForUrlPatterns(null, false, "/myservlet/myendpoint2/*");

Spring Filter For URL Pattern with Path Variable

You are trying to register a filter using the FilterRegistrationBean. As this is a Filter being registered the URL mapping relies on the support of the servlet container not the support in Spring (Boot).

URL mapping of the servlet container is determined by what is specified in the servlet specification (See section 12.2). Which is also mentioned in the javadoc of the addUrlPatterns method.

The URL mapping in the servlet specification is very basic and is only matching the first part of the URL. So that is why your first, /api/user/* works (as the URL starts with /api/user but not /api/user/*/activate because it doesn't start with /api/user/*/activate. It isn't ant-style expression just a simple pattern for the start of a URL.

Spring Boot filter pattern matches wrong urls

The filter pattern is behaving exactly as it should according to the Servlet spec. The spec describes mappings in terms of Servlets, but the same rules apply to Filters too. It provides the following example mappings:

  • /foo/bar/* mapped to servlet1
  • /baz/* mapped to servlet2
  • /catalog mapped to servlet3
  • *.bop mapped to servlet4

Given these mappings, the following behaviour will result:

  • /foo/bar/index.html handled by servlet1
  • /foo/bar/index.bop handled by servlet1
  • /baz handled by servlet2
  • /baz/index.html handled by servlet2
  • /catalog handled by servlet3
  • /catalog/index.html handled by default servlet
  • /catalog/racecar.bop handled by servlet4
  • /index.bop handled by servlet4

The case that you have described is the same as a request for /baz being handled by servlet2 which is mapped to /baz/*.

Is there a different syntax for Spring url patterns to not match these two urls, and only match /users/bob, /users/alice or /users/any_non_empty_string?

As shown by the examples above, the Servlet spec doesn't provide support for such a mapping. You'll need to add some logic to handle that case. You could either do that directly in the filter, or in another filter that runs first and sets a request attribute telling the other filter to ignore the request.

How to config different authentication filter by url pattern?

Through these days online search, I finally found a better implementation.

According to spring official document recommended method.

Creating and Customizing Filter Chains Section:

Many applications have completely different access rules for one set of resources compared to another. For example an application that hosts a UI and a backing API might support cookie-based authentication with a redirect to a login page for the UI parts, and token-based authentication with a 401 response to unauthenticated requests for the API parts. Each set of resources has its own WebSecurityConfigurerAdapter with a unique order and a its own request matcher. If the matching rules overlap the earliest ordered filter chain will win.

class  SecurityConfig {
@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER - 10)
class InternalApiConfig: WebSecurityConfigurerAdapter() {

override fun configure(http: HttpSecurity) {
http.antMatcher("/internal_api/**")
http.authorizeRequests()
.antMatchers("/internal_api/**").authenticated()
http.addFilterAt(JwtTokenAuthFilter("secret1"), UsernamePasswordAuthenticationFilter::class.java)
}
}

@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER - 9)
class ApiConfig : WebSecurityConfigurerAdapter() {

override fun configure(http: HttpSecurity) {
http.authorizeRequests()
.antMatchers("/other_resource/**").authenticated()

http.addFilterAt(JwtTokenAuthFilter("secret2"), UsernamePasswordAuthenticationFilter::class.java)

}
}
}

Annotation for applying filter in spring-boot to specific url patterns

There isn't currently an annotation to do what you want. We do have an open issue to support @WebFilter which we'd like to fix for Spring Boot 1.3.

How do I enable a filter for url that includes a certain word?

In Spring you have two options for handling HTTP request/response. These are using of servlet filter (as you do) or interceptor (link).

Filter can change request/response or even stop HTTP workflow at all. If you got unhandled exception in filter, your request stops working.

Interceptor can't change request/response. It can just listen. Unlike filter if you got unhendled exception in interceptor request doesn't stop working (you just get message in console or log).

Concerning URL pattern: it has very simple syntax. In fact almost all you can do is specifying asterisk at the start or end of the string. *.ext - means files with ext extension. /api/* - means everything starts with /api/. I guess this simplicity made in purpose of performance efficiency. But it doesn't fit your requirements.

There is nothing wrong you use regexp in your filter. It won't affect performance significantly. Everything is OK except of one remark. Regular expression processing consist of two parts: compiling of regexp and matching a string. getRequestURI().matches() does the both parts every time you call it. It would be better to compile regexp just once. Add to your filter:

private static Pattern pattern = Pattern.compile(".*/api/.*");

Then you can use precompiled pattern in filter's method:

@Override
public final void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
...
if (pattern.matcher(request.getRequestURI()).matches()) {
//process query
}
}

This approach allows to avoid recompilation of pattern every time you use it.

spring filter being invoked for all url's and not matching the url pattern

finally resolved this, the url patterns does not effect,have to find an alternate way to do this.
Basically add filter and do not worry url patterns ,but inside filter skip accessing/rejecting header values based on similar logic as below

 uri.startsWith("/swagger")|| uri.startsWith("/webjars")||uri.startsWith("/v2/api-docs");
}

worked in my scenario..can work for a few ppl having similar problem :)



Related Topics



Leave a reply



Submit