Sfoglia il codice sorgente

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 giorni fa
parent
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);
+	}
+
 }