Skip to content

Commit c395da3

Browse files
committed
DelegatingServerLogoutHandler Executes Sequentially
Fixes gh-7723
1 parent 798c48e commit c395da3

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

web/src/main/java/org/springframework/security/web/server/authentication/logout/DelegatingServerLogoutHandler.java

+4-7
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@
2020
import java.util.Arrays;
2121
import java.util.Collection;
2222
import java.util.List;
23-
import java.util.Objects;
24-
import java.util.stream.Collectors;
2523

24+
import reactor.core.publisher.Flux;
2625
import reactor.core.publisher.Mono;
2726

2827
import org.springframework.security.core.Authentication;
@@ -50,10 +49,8 @@ public DelegatingServerLogoutHandler(Collection<ServerLogoutHandler> delegates)
5049

5150
@Override
5251
public Mono<Void> logout(WebFilterExchange exchange, Authentication authentication) {
53-
return Mono.when(this.delegates.stream()
54-
.filter(Objects::nonNull)
55-
.map(delegate -> delegate.logout(exchange, authentication))
56-
.collect(Collectors.toList())
57-
);
52+
return Flux.fromIterable(this.delegates)
53+
.concatMap(delegate -> delegate.logout(exchange, authentication))
54+
.then();
5855
}
5956
}

web/src/test/java/org/springframework/security/web/server/authentication/logout/DelegatingServerLogoutHandlerTests.java

+28
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.security.web.server.authentication.logout;
1818

19+
import static org.assertj.core.api.Assertions.assertThat;
1920
import static org.assertj.core.api.Assertions.assertThatThrownBy;
2021
import static org.mockito.Mockito.*;
2122

@@ -28,9 +29,14 @@
2829
import org.springframework.security.core.Authentication;
2930
import org.springframework.security.web.server.WebFilterExchange;
3031

32+
import reactor.core.publisher.Mono;
3133
import reactor.test.publisher.PublisherProbe;
3234

35+
import java.time.Duration;
3336
import java.util.List;
37+
import java.util.concurrent.CountDownLatch;
38+
import java.util.concurrent.TimeUnit;
39+
import java.util.concurrent.atomic.AtomicBoolean;
3440

3541
/**
3642
* @author Eric Deandrea
@@ -98,4 +104,26 @@ public void logoutWhenMultipleThenExecuted() {
98104
this.delegate1Result.assertWasSubscribed();
99105
this.delegate2Result.assertWasSubscribed();
100106
}
107+
108+
@Test
109+
public void logoutSequential() throws Exception {
110+
AtomicBoolean slowDone = new AtomicBoolean();
111+
CountDownLatch latch = new CountDownLatch(1);
112+
ServerLogoutHandler slow = (exchange, authentication) ->
113+
Mono.delay(Duration.ofMillis(100))
114+
.doOnSuccess(__ -> slowDone.set(true))
115+
.then();
116+
ServerLogoutHandler second = (exchange, authentication) ->
117+
Mono.fromRunnable(() -> {
118+
latch.countDown();
119+
assertThat(slowDone.get())
120+
.describedAs("ServerLogoutHandler should be executed sequentially")
121+
.isTrue();
122+
});
123+
DelegatingServerLogoutHandler handler = new DelegatingServerLogoutHandler(slow, second);
124+
125+
handler.logout(this.exchange, this.authentication).block();
126+
127+
assertThat(latch.await(3, TimeUnit.SECONDS)).isTrue();
128+
}
101129
}

0 commit comments

Comments
 (0)