Env
- spring:2.7.0 with spring-boot-starter-security, spring-boot-starter-web java 17
- on url path antMatcher /v1/ I have Filter1**
- on url path antMatcher /v2/ I have Filter2**
error
- when I do http request to curl.exe localhost:8080/v2/123 I see Filter2, Filter1 are triggered
- when I do http request to curl.exe localhost:8080/v1/43 I see Filter1, Filter2 are triggered
- in startup I see registration of filters is ok
[ restartedMain] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/v1/**'] with [org.springframework.security.web.session.DisableEncodeUrlFilter@1a86246a, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@78d19287, org.springframework.security.web.context.SecurityContextPersistenceFilter@5e7e41ae, org.springframework.security.web.header.HeaderWriterFilter@771cd726, org.springframework.security.web.csrf.CsrfFilter@66bc9b34, org.springframework.security.web.authentication.logout.LogoutFilter@23a3b549, com.example.demo.FilterV1@720f5a38, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@4b2f8dd1, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@c44f810, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@e58d6e8, org.springframework.security.web.session.SessionManagementFilter@1d31806b, org.springframework.security.web.access.ExceptionTranslationFilter@6ea95506, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@149f132f]
[ restartedMain] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/v2/**'] with [org.springframework.security.web.session.DisableEncodeUrlFilter@59e3b068, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@9e1696f, org.springframework.security.web.context.SecurityContextPersistenceFilter@4d4cd988, org.springframework.security.web.header.HeaderWriterFilter@7e807510, org.springframework.security.web.csrf.CsrfFilter@751d0760, org.springframework.security.web.authentication.logout.LogoutFilter@3dfa806b, com.example.demo.FilterV2@47d84948, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@40bd3f4, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@79de1e90, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@770c39d3, org.springframework.security.web.session.SessionManagementFilter@5077e2e1, org.springframework.security.web.access.ExceptionTranslationFilter@4be05dc8, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@1d116d71]
Expected behavior
Filter is triggered only for URL segment whish is defined
Demo
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private FilterV1 filterV1;
@Autowired
private FilterV2 filterV2;
@Bean
@Order(1)
public SecurityFilterChain filterChainV1(HttpSecurity http) throws Exception {
http.antMatcher("/v1/**")
.addFilterBefore(filterV1, UsernamePasswordAuthenticationFilter.class)
.authorizeRequests().anyRequest().authenticated()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
@Bean
@Order(2)
public SecurityFilterChain filterChainV2(HttpSecurity http) throws Exception {
http.antMatcher("/v2/**")
.addFilterBefore(filterV2, UsernamePasswordAuthenticationFilter.class)
.authorizeRequests().anyRequest().authenticated()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
}
Comment From: mdeinum
When Spring Boot detects a servlet filter it automatically registers it with the regular filter chain so each filter will be always executed in this case. As mentioned here in the documentation. If you don't want this to happen, because you want to add them in the security chain, you need to add an explicit FilterRegistrationBean to disable it (as mentioned here).
See also: * https://stackoverflow.com/questions/39314176/filter-invoke-twice-when-register-as-spring-bean * https://stackoverflow.com/questions/64241555/spring-boot-filter-called-twice-or-not-called-at-all * https://stackoverflow.com/questions/24381191/what-is-implication-of-adding-component-to-custom-spring-security-filter * https://stackoverflow.com/questions/64090329/spring-security-custom-filter-gets-called-multiple-times/64107238#64107238 * https://stackoverflow.com/questions/44775539/why-spring-boot-filter-call-twice/60045285#60045285
For the Spring Boot Team, this keeps popping up quite regularly on StackOverflow as well. Would it make sense to have a marker annotation (something like @SecurityFilter for either on the class or @Bean method) and have it be ignored by the framework from auto registration instead of explicitly having to add a FilterRegistrationBean to disable it?
Comment From: wilkinsona
Thanks, @mdeinum.
For the Spring Boot Team, this keeps popping up quite regularly on StackOverflow as well. Would it make sense to have a marker annotation (something like @SecurityFilter for either on the class or @Bean method) and have it be ignored by the framework from auto registration instead of explicitly having to add a FilterRegistrationBean to disable it?
Yes, I think so. https://github.com/spring-projects/spring-boot/issues/16500 is tracking some sort of enhancement in this area.
Comment From: sysmat
@mdeinum thx, @SecurityFilter or @FilterRegistration(order=200, urlPatterns={"/path/**"}) it would be very nice
Comment From: sysmat
- spring-boot-starter-parent:3.0.3 now none of filters work
- is in this framework such a problem with url path1 apply filter 1, on url path2 apply filter 2
Comment From: wilkinsona
@sysmat I don't see the connection between your latest comment and the rest of this issue. An upgrade to Spring Boot 3.0.3 brings with it an upgrade to Spring Security 6.0. Please check the relevant section of Spring Boot's migration guide and the Spring Security documentation to which it links. If this doesn't help, please open a new issue with a complete yet minimal sample that reproduces the problem.
Comment From: sysmat
@wilkinsona thx for link to migration, but there is nothing of sort braking changes about EnableWebSecurity, SecurityFilterChain, antMatcher, HttpSecurity, OncePerRequestFilter
Comment From: sysmat
- now none of filter are even triggered
- response is still HTTP.status=401
- in HttpSecurity not clear even which matching method should be used
Comment From: sysmat
- HttpSecurity has builder pattern, but in my opinion it has to big public area, for DX is not clear with which method should start configuring it
Comment From: sysmat
- TRACE logging:
2023-03-11T11:14:53.821+01:00 DEBUG 26892 --- [nio-8080-exec-9] o.a.coyote.http11.Http11InputBuffer : Received [GET /frontend/avs/12 HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzIjoiYSJ9.UvNTLEJ_WiRCWQFMvBJQt-Pa_nqinwihcyjn1Tl4Zso
User-Agent: PostmanRuntime/7.31.1
Accept: */*
Cache-Control: no-cache
Postman-Token: 07f604e6-5744-47ec-a095-735dd9023e3b
Host: localhost:8080
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: JSESSIONID=B10628047C768A140627ECA2E0F6030C
]
2023-03-11T11:14:53.821+01:00 DEBUG 26892 --- [nio-8080-exec-9] o.a.t.util.http.Rfc6265CookieProcessor : Cookies: Parsing b[]: JSESSIONID=B10628047C768A140627ECA2E0F6030C
2023-03-11T11:14:53.821+01:00 DEBUG 26892 --- [nio-8080-exec-9] o.a.catalina.connector.CoyoteAdapter : Requested cookie session id is B10628047C768A140627ECA2E0F6030C
2023-03-11T11:14:53.821+01:00 DEBUG 26892 --- [nio-8080-exec-9] o.a.c.authenticator.AuthenticatorBase : Security checking request GET /frontend/avs/12
2023-03-11T11:14:53.821+01:00 DEBUG 26892 --- [nio-8080-exec-9] org.apache.catalina.realm.RealmBase : No applicable constraints defined
2023-03-11T11:14:53.821+01:00 DEBUG 26892 --- [nio-8080-exec-9] o.a.c.authenticator.AuthenticatorBase : Not subject to any constraint
2023-03-11T11:14:53.821+01:00 DEBUG 26892 --- [nio-8080-exec-9] o.apache.catalina.core.StandardWrapper : Returning instance
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.b.w.s.f.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade@8b37e1f
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.session.DisableEncodeUrlFilter@4ccd89e7, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1ac5b54, org.springframework.security.web.context.SecurityContextHolderFilter@68d716d7, org.springframework.security.web.header.HeaderWriterFilter@6d541b4f, org.springframework.security.web.csrf.CsrfFilter@117aa7f3, org.springframework.security.web.authentication.logout.LogoutFilter@2b87b5e7, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@7930cacc, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@64f757e0, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@7eb58707, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@6f8e7080, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2cd67101, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@29b4bffa, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@62a3e221, org.springframework.security.web.access.ExceptionTranslationFilter@2b45d45d, org.springframework.security.web.access.intercept.AuthorizationFilter@79569f5d]] (1/1)
2023-03-11T11:14:53.822+01:00 DEBUG 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Securing GET /frontend/avs/12
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking DisableEncodeUrlFilter (1/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking WebAsyncManagerIntegrationFilter (2/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderFilter (3/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking HeaderWriterFilter (4/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking CsrfFilter (5/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.csrf.CsrfFilter : Did not protect against CSRF since request did not match CsrfNotRequired [TRACE, HEAD, GET, OPTIONS]
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking LogoutFilter (6/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.s.w.a.logout.LogoutFilter : Did not match request to Ant [pattern='/logout', POST]
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking UsernamePasswordAuthenticationFilter (7/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] w.a.UsernamePasswordAuthenticationFilter : Did not match request to Ant [pattern='/login', POST]
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking DefaultLoginPageGeneratingFilter (8/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking DefaultLogoutPageGeneratingFilter (9/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] .w.a.u.DefaultLogoutPageGeneratingFilter : Did not render default logout page since request did not match [Ant [pattern='/logout', GET]]
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking BasicAuthenticationFilter (10/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.s.w.a.www.BasicAuthenticationFilter : Did not process authentication request since failed to find username and password in Basic Authorization header
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking RequestCacheAwareFilter (11/15)
2023-03-11T11:14:53.822+01:00 DEBUG 26892 --- [nio-8080-exec-9] org.apache.tomcat.util.http.Parameters : Set encoding to UTF-8
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.s.w.s.HttpSessionRequestCache : matchingRequestParameterName is required for getMatchingRequest to lookup a value, but not provided
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderAwareRequestFilter (12/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking AnonymousAuthenticationFilter (13/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking ExceptionTranslationFilter (14/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : Invoking AuthorizationFilter (15/15)
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] estMatcherDelegatingAuthorizationManager : Authorizing SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@6748179]
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] estMatcherDelegatingAuthorizationManager : Checking authorization on SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@6748179] using org.springframework.security.authorization.AuthenticatedAuthorizationManager@4ed4d7a4
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : Did not find SecurityContext in HttpSession B10628047C768A140627ECA2E0F6030C using the SPRING_SECURITY_CONTEXT session attribute
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] .s.s.w.c.SupplierDeferredSecurityContext : Created SecurityContextImpl [Null authentication]
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] .s.s.w.c.SupplierDeferredSecurityContext : Created SecurityContextImpl [Null authentication]
2023-03-11T11:14:53.822+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=B10628047C768A140627ECA2E0F6030C], Granted Authorities=[ROLE_ANONYMOUS]]
2023-03-11T11:14:53.823+01:00 TRACE 26892 --- [nio-8080-exec-9] o.s.s.w.a.ExceptionTranslationFilter : Sending AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=B10628047C768A140627ECA2E0F6030C], Granted Authorities=[ROLE_ANONYMOUS]] to authentication entry point since access is denied
- my filters are registered but apparently newer matched
Comment From: wilkinsona
@sysmat As I said above, this belongs in a separate issue and needs to be accompanied by a minimal sample that reproduces the problem. From what's you've shown this far, that issue should be a Spring Security issue.