From 62c50158bb6dcbe36451351768c6ae47961847eb Mon Sep 17 00:00:00 2001 From: Andrey Litvitski Date: Thu, 5 Jun 2025 17:17:42 +0300 Subject: [PATCH] override `OncePerRequestFilter#getAlreadyFilteredAttributeName` in `AuthenticationFilter` (#17173) Signed-off-by: Andrey Litvitski --- .../authentication/AuthenticationFilter.java | 12 +++++++++++- .../AuthenticationFilterTests.java | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/web/src/main/java/org/springframework/security/web/authentication/AuthenticationFilter.java b/web/src/main/java/org/springframework/security/web/authentication/AuthenticationFilter.java index e4b752fd39f..b452be48921 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/AuthenticationFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/AuthenticationFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,6 +64,7 @@ * * * @author Sergey Bespalov + * @author Andrey Litvitski * @since 5.2.0 */ public class AuthenticationFilter extends OncePerRequestFilter { @@ -222,4 +223,13 @@ private Authentication attemptAuthentication(HttpServletRequest request, HttpSer return authenticationResult; } + @Override + protected String getAlreadyFilteredAttributeName() { + String name = getFilterName(); + if (name == null) { + name = getClass().getName().concat("-" + System.identityHashCode(this)); + } + return name + ALREADY_FILTERED_SUFFIX; + } + } diff --git a/web/src/test/java/org/springframework/security/web/authentication/AuthenticationFilterTests.java b/web/src/test/java/org/springframework/security/web/authentication/AuthenticationFilterTests.java index b4ab4411e44..3619ade8132 100644 --- a/web/src/test/java/org/springframework/security/web/authentication/AuthenticationFilterTests.java +++ b/web/src/test/java/org/springframework/security/web/authentication/AuthenticationFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.security.web.authentication; import jakarta.servlet.FilterChain; +import jakarta.servlet.Servlet; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; @@ -57,6 +58,7 @@ /** * @author Sergey Bespalov + * @author Andrey Litvitski * @since 5.2.0 */ @ExtendWith(MockitoExtension.class) @@ -318,4 +320,18 @@ public void filterWhenCustomSecurityContextRepositoryAndSuccessfulAuthentication assertThat(securityContextArg.getValue().getAuthentication()).isEqualTo(authentication); } + @Test + public void filterWhenInFilterChainThenBothAreExecuted() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/"); + MockHttpServletResponse response = new MockHttpServletResponse(); + AuthenticationFilter filter1 = new AuthenticationFilter(this.authenticationManager, + this.authenticationConverter); + AuthenticationConverter converter2 = mock(AuthenticationConverter.class); + AuthenticationFilter filter2 = new AuthenticationFilter(this.authenticationManager, converter2); + FilterChain chain = new MockFilterChain(mock(Servlet.class), filter1, filter2); + chain.doFilter(request, response); + verify(this.authenticationConverter).convert(any()); + verify(converter2).convert(any()); + } + }