Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.7.0: SecurityFilterChain antMatcher trigger all the filters on not matching route #31511

Closed
sysmat opened this issue Jun 23, 2022 · 10 comments
Closed
Labels
status: duplicate A duplicate of another issue

Comments

@sysmat
Copy link

sysmat commented Jun 23, 2022

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();
    }

}

demo.zip

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 23, 2022
@sysmat sysmat changed the title SecurityFilterChain antMatcher trigger all the filters on not matching route 2.7.0: SecurityFilterChain antMatcher trigger all the filters on not matching route Jun 23, 2022
@mdeinum
Copy link
Contributor

mdeinum commented Jun 23, 2022

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:

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?

@wilkinsona
Copy link
Member

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. #16500 is tracking some sort of enhancement in this area.

@wilkinsona wilkinsona closed this as not planned Won't fix, can't repro, duplicate, stale Jun 23, 2022
@wilkinsona wilkinsona added status: duplicate A duplicate of another issue and removed status: waiting-for-triage An issue we've not yet triaged labels Jun 23, 2022
@sysmat
Copy link
Author

sysmat commented Jun 23, 2022

@mdeinum thx, @SecurityFilter or @FilterRegistration(order=200, urlPatterns={"/path/**"}) it would be very nice

@sysmat sysmat closed this as completed Jun 23, 2022
@snicoll snicoll closed this as not planned Won't fix, can't repro, duplicate, stale Jun 23, 2022
@sysmat
Copy link
Author

sysmat commented Mar 10, 2023

  • 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

@wilkinsona
Copy link
Member

@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.

@sysmat
Copy link
Author

sysmat commented Mar 11, 2023

@wilkinsona thx for link to migration, but there is nothing of sort braking changes about EnableWebSecurity, SecurityFilterChain, antMatcher, HttpSecurity, OncePerRequestFilter

@sysmat
Copy link
Author

sysmat commented Mar 11, 2023

  • now none of filter are even triggered
  • response is still HTTP.status=401
  • in HttpSecurity not clear even which matching method should be used

@sysmat
Copy link
Author

sysmat commented Mar 11, 2023

  • 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

@sysmat
Copy link
Author

sysmat commented Mar 11, 2023

  • 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

@wilkinsona
Copy link
Member

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

5 participants