DelegatingServerLogoutHandler Executes Sequentially

Fixes gh-7723
This commit is contained in:
Rob Winch 2019-12-11 15:39:27 -06:00
parent 798c48eee3
commit c395da3e04
2 changed files with 32 additions and 7 deletions

View File

@ -20,9 +20,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.security.core.Authentication;
@ -50,10 +49,8 @@ public class DelegatingServerLogoutHandler implements ServerLogoutHandler {
@Override
public Mono<Void> logout(WebFilterExchange exchange, Authentication authentication) {
return Mono.when(this.delegates.stream()
.filter(Objects::nonNull)
.map(delegate -> delegate.logout(exchange, authentication))
.collect(Collectors.toList())
);
return Flux.fromIterable(this.delegates)
.concatMap(delegate -> delegate.logout(exchange, authentication))
.then();
}
}

View File

@ -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();
}
}