Parcourir la source

Fix to allow multiple AuthenticationFilter instances to process each request

Closes gh-17173

Signed-off-by: Andrey Litvitski <andrey1010102008@gmail.com>
Andrey Litvitski il y a 2 mois
Parent
commit
b0f8aa5ea0

+ 11 - 1
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 @@ import org.springframework.web.filter.OncePerRequestFilter;
  * </ul>
  *
  * @author Sergey Bespalov
+ * @author Andrey Litvitski
  * @since 5.2.0
  */
 public class AuthenticationFilter extends OncePerRequestFilter {
@@ -193,6 +194,15 @@ public class AuthenticationFilter extends OncePerRequestFilter {
 		}
 	}
 
+	@Override
+	protected String getAlreadyFilteredAttributeName() {
+		String name = getFilterName();
+		if (name == null) {
+			name = getClass().getName().concat("-" + System.identityHashCode(this));
+		}
+		return name + ALREADY_FILTERED_SUFFIX;
+	}
+
 	private void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
 			AuthenticationException failed) throws IOException, ServletException {
 		this.securityContextHolderStrategy.clearContext();

+ 17 - 1
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 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 /**
  * @author Sergey Bespalov
+ * @author Andrey Litvitski
  * @since 5.2.0
  */
 @ExtendWith(MockitoExtension.class)
@@ -318,4 +320,18 @@ public class AuthenticationFilterTests {
 		assertThat(securityContextArg.getValue().getAuthentication()).isEqualTo(authentication);
 	}
 
+	@Test
+	public void filterWhenMultipleInChainThenAllFiltered() 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());
+	}
+
 }