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 toservlet1
/baz/*
mapped toservlet2
/catalog
mapped toservlet3
*.bop
mapped toservlet4
Given these mappings, the following behaviour will result:
/foo/bar/index.html
handled byservlet1
/foo/bar/index.bop
handled byservlet1
/baz
handled byservlet2
/baz/index.html
handled byservlet2
/catalog
handled byservlet3
/catalog/index.html
handled bydefault servlet
/catalog/racecar.bop
handled byservlet4
/index.bop
handled byservlet4
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
How to Restart a Java Program Here
Java Spring @Scheduled Tasks Executing Twice
How to Clean Project Cache in Intellij Idea Like Eclipse'S Clean
Spring Boot - Json Object Array to Java Array
Appbar Not Showing Back Button
Array Pairwise Matching in Java Give Error Also Store Data Between Two Similar Element
Random Number Generation Without Repetition in Java
Hibernate Error - Querysyntaxexception: Users Is Not Mapped [From Users]
Replacing Double Backslashes With Single Backslash
Refreshing Existing Windows in Java Swing
How to Delete the Content of Text File Without Deleting Itself
In Junit 5, How to Run Code Before All Tests
Spring Boot Controller Not Mapping
Java Error Message. Unexpected Type, Required Variable, Found Value
Jdk Tools.Jar as Maven Dependency
Java 8 Lambda for Selecting Top Salary Employee for Each Department