Verify ReactorContext when using Virtual Threads
Closes gh-12791
This commit is contained in:
+57
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,10 +16,17 @@
|
||||
|
||||
package org.springframework.security.core.context;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledOnJre;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.task.VirtualThreadTaskExecutor;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
@@ -99,4 +106,53 @@ public class ReactiveSecurityContextHolderTests {
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getContextWhenThreadFactoryIsPlatformThenPropagated() {
|
||||
verifySecurityContextIsPropagated(Executors.defaultThreadFactory());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisabledOnJre(JRE.JAVA_17)
|
||||
public void getContextWhenThreadFactoryIsVirtualThenPropagated() {
|
||||
verifySecurityContextIsPropagated(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
|
||||
}
|
||||
|
||||
private static void verifySecurityContextIsPropagated(ThreadFactory threadFactory) {
|
||||
Authentication authentication = new TestingAuthenticationToken("user", null);
|
||||
|
||||
// @formatter:off
|
||||
Mono<Authentication> publisher = ReactiveSecurityContextHolder.getContext()
|
||||
.map(SecurityContext::getAuthentication)
|
||||
.contextWrite((context) -> ReactiveSecurityContextHolder.withAuthentication(authentication))
|
||||
.subscribeOn(Schedulers.newSingle(threadFactory));
|
||||
// @formatter:on
|
||||
|
||||
StepVerifier.create(publisher).expectNext(authentication).verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearContextWhenThreadFactoryIsPlatformThenCleared() {
|
||||
verifySecurityContextIsCleared(Executors.defaultThreadFactory());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisabledOnJre(JRE.JAVA_17)
|
||||
public void clearContextWhenThreadFactoryIsVirtualThenCleared() {
|
||||
verifySecurityContextIsCleared(new VirtualThreadTaskExecutor().getVirtualThreadFactory());
|
||||
}
|
||||
|
||||
private static void verifySecurityContextIsCleared(ThreadFactory threadFactory) {
|
||||
Authentication authentication = new TestingAuthenticationToken("user", null);
|
||||
|
||||
// @formatter:off
|
||||
Mono<Authentication> publisher = ReactiveSecurityContextHolder.getContext()
|
||||
.map(SecurityContext::getAuthentication)
|
||||
.contextWrite(ReactiveSecurityContextHolder.clearContext())
|
||||
.contextWrite((context) -> ReactiveSecurityContextHolder.withAuthentication(authentication))
|
||||
.subscribeOn(Schedulers.newSingle(threadFactory));
|
||||
// @formatter:on
|
||||
|
||||
StepVerifier.create(publisher).verifyComplete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user