Forráskód Böngészése

DelegatingAuthenticationEntryPoint.Builder allows just defaultEntryPoint

Previously build threw an Exception when entryPoints was empty and
defaultEntryPoint was specified.

This commit changes build to return the defaultEntryPoint instead.

Closes gh-17955
Rob Winch 6 napja
szülő
commit
029e31ebe8

+ 4 - 1
web/src/main/java/org/springframework/security/web/authentication/DelegatingAuthenticationEntryPoint.java

@@ -211,15 +211,18 @@ public class DelegatingAuthenticationEntryPoint implements AuthenticationEntryPo
 		 * @return the {@link AuthenticationEntryPoint} to use.
 		 */
 		public AuthenticationEntryPoint build() {
-			Assert.notEmpty(this.entryPoints, "entryPoints cannot be empty");
 			AuthenticationEntryPoint defaultEntryPoint = this.defaultEntryPoint;
 			if (defaultEntryPoint == null) {
+				Assert.state(!this.entryPoints.isEmpty(), "entryPoints cannot be empty if defaultEntryPoint is null");
 				AuthenticationEntryPoint firstAuthenticationEntryPoint = this.entryPoints.get(0).getEntry();
 				if (this.entryPoints.size() == 1) {
 					return firstAuthenticationEntryPoint;
 				}
 				defaultEntryPoint = firstAuthenticationEntryPoint;
 			}
+			else if (this.entryPoints.isEmpty()) {
+				return defaultEntryPoint;
+			}
 			return new DelegatingAuthenticationEntryPoint(defaultEntryPoint, this.entryPoints);
 		}
 

+ 51 - 0
web/src/test/java/org/springframework/security/web/authentication/DelegatingAuthenticationEntryPointTests.java

@@ -16,10 +16,12 @@
 
 package org.springframework.security.web.authentication;
 
+import java.io.IOException;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
 
+import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServletRequest;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -29,11 +31,15 @@ import org.springframework.security.web.AuthenticationEntryPoint;
 import org.springframework.security.web.util.matcher.RequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcherEntry;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
 
 /**
  * Test class for {@link DelegatingAuthenticationEntryPoint}
@@ -202,4 +208,49 @@ public class DelegatingAuthenticationEntryPointTests {
 		verify(this.defaultEntryPoint, never()).commence(this.request, null, null);
 	}
 
+	@Test
+	void builderWhenDefaultNullAndSingleEntryPointThenReturnsSingle() {
+		AuthenticationEntryPoint entryPoint = mock(AuthenticationEntryPoint.class);
+
+		AuthenticationEntryPoint result = DelegatingAuthenticationEntryPoint.builder()
+			.addEntryPointFor(entryPoint, mock(RequestMatcher.class))
+			.build();
+
+		assertThat(result).isEqualTo(entryPoint);
+	}
+
+	@Test
+	void builderWhenDefaultNullThenFirstIsDefault() throws ServletException, IOException {
+		AuthenticationEntryPoint firstEntryPoint = mock(AuthenticationEntryPoint.class);
+		AuthenticationEntryPoint secondEntryPoint = mock(AuthenticationEntryPoint.class);
+		RequestMatcher neverMatch = mock(RequestMatcher.class);
+		given(neverMatch.matches(this.request)).willReturn(false);
+		AuthenticationEntryPoint result = DelegatingAuthenticationEntryPoint.builder()
+			.addEntryPointFor(firstEntryPoint, neverMatch)
+			.addEntryPointFor(secondEntryPoint, neverMatch)
+			.build();
+
+		result.commence(this.request, null, null);
+
+		verify(firstEntryPoint).commence(any(), any(), any());
+		verifyNoInteractions(secondEntryPoint);
+	}
+
+	@Test
+	void builderWhenDefaultAndEmptyEntryPointsThenReturnsDefault() {
+		AuthenticationEntryPoint defaultEntryPoint = mock(AuthenticationEntryPoint.class);
+
+		AuthenticationEntryPoint result = DelegatingAuthenticationEntryPoint.builder()
+			.defaultEntryPoint(defaultEntryPoint)
+			.build();
+
+		assertThat(result).isEqualTo(defaultEntryPoint);
+	}
+
+	@Test
+	void builderWhenNoEntryPointsThenIllegalStateException() {
+		DelegatingAuthenticationEntryPoint.Builder builder = DelegatingAuthenticationEntryPoint.builder();
+		assertThatIllegalStateException().isThrownBy(builder::build);
+	}
+
 }