فهرست منبع

Only populate a Context once

Fixes gh-4718
Rob Winch 7 سال پیش
والد
کامیت
3bceadd369

+ 6 - 0
test/src/main/java/org/springframework/security/test/context/support/ReactorContextTestExecutionListener.java

@@ -63,6 +63,8 @@ public class ReactorContextTestExecutionListener
 		}
 
 		private static class SecuritySubContext<T> implements CoreSubscriber<T> {
+			private static String CONTEXT_DEFAULTED_ATTR_NAME = SecuritySubContext.class.getName().concat(".CONTEXT_DEFAULTED_ATTR_NAME");
+
 			private final CoreSubscriber<T> delegate;
 
 			SecuritySubContext(CoreSubscriber<T> delegate) {
@@ -72,6 +74,10 @@ public class ReactorContextTestExecutionListener
 			@Override
 			public Context currentContext() {
 				Context context = delegate.currentContext();
+				if(context.hasKey(CONTEXT_DEFAULTED_ATTR_NAME)) {
+					return context;
+				}
+				context = context.put(CONTEXT_DEFAULTED_ATTR_NAME, Boolean.TRUE);
 				Authentication authentication = TestSecurityContextHolder.getContext().getAuthentication();
 				if (authentication == null) {
 					return context;

+ 18 - 0
test/src/test/java/org/springframework/security/test/context/support/ReactorContextTestExecutionListenerTests.java

@@ -111,6 +111,24 @@ public class ReactorContextTestExecutionListenerTests {
 			.verifyComplete();
 	}
 
+	@Test
+	public void beforeTestMethodWhenClearThenReactorContextDoesNotOverride() throws Exception {
+		TestingAuthenticationToken expectedAuthentication = new TestingAuthenticationToken("user", "password", "ROLE_USER");
+		TestingAuthenticationToken contextHolder = new TestingAuthenticationToken("contextHolder", "password", "ROLE_USER");
+		TestSecurityContextHolder.setContext(new SecurityContextImpl(contextHolder));
+
+		this.listener.beforeTestMethod(this.testContext);
+
+		Mono<Authentication> authentication = Mono.just("any")
+			.flatMap(s -> ReactiveSecurityContextHolder.getContext()
+				.map(SecurityContext::getAuthentication)
+			)
+			.subscriberContext(ReactiveSecurityContextHolder.clearContext());
+
+		StepVerifier.create(authentication)
+			.verifyComplete();
+	}
+
 	@Test
 	public void afterTestMethodWhenSecurityContextEmptyThenNoError() throws Exception {
 		this.listener.beforeTestMethod(this.testContext);