2
0
Эх сурвалжийг харах

DelegatingServerLogoutHandler Executes Sequentially

Fixes gh-7723
Rob Winch 5 жил өмнө
parent
commit
73babc3314

+ 4 - 7
web/src/main/java/org/springframework/security/web/server/authentication/logout/DelegatingServerLogoutHandler.java

@@ -21,6 +21,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 
+import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
 import org.springframework.security.core.Authentication;
@@ -48,12 +49,8 @@ public class DelegatingServerLogoutHandler implements ServerLogoutHandler {
 
 	@Override
 	public Mono<Void> logout(WebFilterExchange exchange, Authentication authentication) {
-		List<Mono<Void>> results = new ArrayList<>();
-		for (ServerLogoutHandler delegate : delegates) {
-			if (delegate != null) {
-				results.add(delegate.logout(exchange, authentication));
-			}
-		}
-		return Mono.when(results);
+		return Flux.fromIterable(this.delegates)
+			.concatMap(delegate -> delegate.logout(exchange, authentication))
+			.then();
 	}
 }

+ 28 - 0
web/src/test/java/org/springframework/security/web/server/authentication/logout/DelegatingServerLogoutHandlerTests.java

@@ -16,6 +16,7 @@
 
 package org.springframework.security.web.server.authentication.logout;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Mockito.*;
 
@@ -28,9 +29,14 @@ import org.mockito.junit.MockitoJUnitRunner;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.web.server.WebFilterExchange;
 
+import reactor.core.publisher.Mono;
 import reactor.test.publisher.PublisherProbe;
 
+import java.time.Duration;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * @author Eric Deandrea
@@ -98,4 +104,26 @@ public class DelegatingServerLogoutHandlerTests {
 		this.delegate1Result.assertWasSubscribed();
 		this.delegate2Result.assertWasSubscribed();
 	}
+
+	@Test
+	public void logoutSequential() throws Exception {
+		AtomicBoolean slowDone = new AtomicBoolean();
+		CountDownLatch latch = new CountDownLatch(1);
+		ServerLogoutHandler slow = (exchange, authentication) ->
+			Mono.delay(Duration.ofMillis(100))
+				.doOnSuccess(__ -> slowDone.set(true))
+				.then();
+		ServerLogoutHandler second = (exchange, authentication) ->
+			Mono.fromRunnable(() -> {
+				latch.countDown();
+				assertThat(slowDone.get())
+					.describedAs("ServerLogoutHandler should be executed sequentially")
+					.isTrue();
+			});
+		DelegatingServerLogoutHandler handler = new DelegatingServerLogoutHandler(slow, second);
+
+		handler.logout(this.exchange, this.authentication).block();
+
+		assertThat(latch.await(3, TimeUnit.SECONDS)).isTrue();
+	}
 }