fix Mock Authentication resolution
This commit is contained in:
parent
b640d84b12
commit
76e36bd06e
|
@ -19,6 +19,7 @@ package org.springframework.security.test.context.support;
|
|||
import org.reactivestreams.Subscription;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.test.context.TestSecurityContextHolder;
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.TestExecutionListener;
|
||||
|
@ -54,7 +55,8 @@ public class ReactorContextTestExecutionListener
|
|||
private static class DelegateTestExecutionListener extends AbstractTestExecutionListener {
|
||||
@Override
|
||||
public void beforeTestMethod(TestContext testContext) throws Exception {
|
||||
Hooks.onLastOperator(Operators.lift((s, sub) -> new SecuritySubContext<>(sub)));
|
||||
SecurityContext securityContext = TestSecurityContextHolder.getContext();
|
||||
Hooks.onLastOperator(Operators.lift((s, sub) -> new SecuritySubContext<>(sub, securityContext)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,9 +68,11 @@ public class ReactorContextTestExecutionListener
|
|||
private static String CONTEXT_DEFAULTED_ATTR_NAME = SecuritySubContext.class.getName().concat(".CONTEXT_DEFAULTED_ATTR_NAME");
|
||||
|
||||
private final CoreSubscriber<T> delegate;
|
||||
private final SecurityContext securityContext;
|
||||
|
||||
SecuritySubContext(CoreSubscriber<T> delegate) {
|
||||
SecuritySubContext(CoreSubscriber<T> delegate, SecurityContext securityContext) {
|
||||
this.delegate = delegate;
|
||||
this.securityContext = securityContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,7 +82,7 @@ public class ReactorContextTestExecutionListener
|
|||
return context;
|
||||
}
|
||||
context = context.put(CONTEXT_DEFAULTED_ATTR_NAME, Boolean.TRUE);
|
||||
Authentication authentication = TestSecurityContextHolder.getContext().getAuthentication();
|
||||
Authentication authentication = securityContext.getAuthentication();
|
||||
if (authentication == null) {
|
||||
return context;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ package org.springframework.security.test.context.support;
|
|||
* @since 5.0
|
||||
*/
|
||||
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -153,6 +155,18 @@ public class ReactorContextTestExecutionListenerTests {
|
|||
assertThat(comparator.compare(withSecurity, reactorContext)).isLessThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkSecurityContextResolutionWhenSubscribedContextCalledOnTheDifferentThreadThanWithSecurityContextTestExecutionListener() throws Exception {
|
||||
TestingAuthenticationToken contextHolder = new TestingAuthenticationToken("contextHolder", "password", "ROLE_USER");
|
||||
TestSecurityContextHolder.setContext(new SecurityContextImpl(contextHolder));
|
||||
|
||||
this.listener.beforeTestMethod(this.testContext);
|
||||
|
||||
ForkJoinPool.commonPool()
|
||||
.submit(() -> assertAuthentication(contextHolder))
|
||||
.join();
|
||||
}
|
||||
|
||||
public void assertAuthentication(Authentication expected) {
|
||||
Mono<Authentication> authentication = ReactiveSecurityContextHolder.getContext()
|
||||
.map(SecurityContext::getAuthentication);
|
||||
|
|
|
@ -52,7 +52,7 @@ abstract class AbstractMockServerConfigurersTests {
|
|||
|
||||
@RestController
|
||||
protected static class PrincipalController {
|
||||
Principal principal;
|
||||
volatile Principal principal;
|
||||
|
||||
@RequestMapping("/**")
|
||||
public Principal get(Principal principal) {
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.security.test.web.reactive.server;
|
||||
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
@ -114,4 +116,54 @@ public class SecurityMockServerConfigurersAnnotatedTests extends AbstractMockSer
|
|||
|
||||
assertPrincipalCreatedFromUserDetails(controller.removePrincipal(), userBuilder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
public void withMockUserWhenOnMethodAndRequestIsExecutedOnDifferentThreadThenSuccess() {
|
||||
Authentication authentication = TestSecurityContextHolder.getContext().getAuthentication();
|
||||
ForkJoinPool
|
||||
.commonPool()
|
||||
.submit(() ->
|
||||
client
|
||||
.get()
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
)
|
||||
.join();
|
||||
|
||||
controller.assertPrincipalIsEqualTo(authentication);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser
|
||||
public void withMockUserAndWithCallOnSeparateThreadWhenMutateWithMockPrincipalAndNoMutateThenOverridesAnnotationAndUsesAnnotation() {
|
||||
TestingAuthenticationToken authentication = new TestingAuthenticationToken("authentication", "secret", "ROLE_USER");
|
||||
|
||||
ForkJoinPool
|
||||
.commonPool()
|
||||
.submit(() ->
|
||||
client
|
||||
.mutateWith(mockAuthentication(authentication))
|
||||
.get()
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
)
|
||||
.join();
|
||||
|
||||
controller.assertPrincipalIsEqualTo(authentication);
|
||||
|
||||
|
||||
ForkJoinPool
|
||||
.commonPool()
|
||||
.submit(() ->
|
||||
client
|
||||
.get()
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
)
|
||||
.join();
|
||||
|
||||
assertPrincipalCreatedFromUserDetails(controller.removePrincipal(), userBuilder.build());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue