mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-11-02 23:58:57 +00:00
SecurityMockServerConfiguers fixes
Issue: gh-4719
This commit is contained in:
parent
77aedcf502
commit
c467dcdbe1
@ -26,7 +26,6 @@ import org.springframework.security.core.context.SecurityContext;
|
|||||||
import org.springframework.security.core.context.SecurityContextImpl;
|
import org.springframework.security.core.context.SecurityContextImpl;
|
||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.core.userdetails.User;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.test.context.TestSecurityContextHolder;
|
|
||||||
import org.springframework.test.web.reactive.server.MockServerConfigurer;
|
import org.springframework.test.web.reactive.server.MockServerConfigurer;
|
||||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
import org.springframework.test.web.reactive.server.WebTestClientConfigurer;
|
import org.springframework.test.web.reactive.server.WebTestClientConfigurer;
|
||||||
@ -39,6 +38,7 @@ import reactor.core.publisher.Mono;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test utilities for working with Spring Security and
|
* Test utilities for working with Spring Security and
|
||||||
@ -58,7 +58,6 @@ public class SecurityMockServerConfigurers {
|
|||||||
public void beforeServerCreated(WebHttpHandlerBuilder builder) {
|
public void beforeServerCreated(WebHttpHandlerBuilder builder) {
|
||||||
builder.filters( filters -> {
|
builder.filters( filters -> {
|
||||||
filters.add(0, new MutatorFilter());
|
filters.add(0, new MutatorFilter());
|
||||||
filters.add(0, new SetupMutatorFilter(TestSecurityContextHolder.getContext()));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -71,7 +70,7 @@ public class SecurityMockServerConfigurers {
|
|||||||
* @return the {@link WebTestClientConfigurer}} to use
|
* @return the {@link WebTestClientConfigurer}} to use
|
||||||
*/
|
*/
|
||||||
public static <T extends WebTestClientConfigurer & MockServerConfigurer> T mockAuthentication(Authentication authentication) {
|
public static <T extends WebTestClientConfigurer & MockServerConfigurer> T mockAuthentication(Authentication authentication) {
|
||||||
return (T) new MutatorWebTestClientConfigurer(authentication);
|
return (T) new MutatorWebTestClientConfigurer(() -> Mono.just(authentication).map(SecurityContextImpl::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -216,21 +215,11 @@ public class SecurityMockServerConfigurers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class MutatorWebTestClientConfigurer implements WebTestClientConfigurer, MockServerConfigurer {
|
private static class MutatorWebTestClientConfigurer implements WebTestClientConfigurer, MockServerConfigurer {
|
||||||
private final Mono<SecurityContext> context;
|
private final Supplier<Mono<SecurityContext>> context;
|
||||||
|
|
||||||
private MutatorWebTestClientConfigurer(Mono<SecurityContext> context) {
|
private MutatorWebTestClientConfigurer(Supplier<Mono<SecurityContext>> context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MutatorWebTestClientConfigurer(SecurityContext context) {
|
|
||||||
this(Mono.just(context));
|
|
||||||
}
|
|
||||||
|
|
||||||
private MutatorWebTestClientConfigurer(Authentication authentication) {
|
|
||||||
this(new SecurityContextImpl(authentication));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeServerCreated(WebHttpHandlerBuilder builder) {
|
public void beforeServerCreated(WebHttpHandlerBuilder builder) {
|
||||||
builder.filters(addSetupMutatorFilter());
|
builder.filters(addSetupMutatorFilter());
|
||||||
@ -247,20 +236,12 @@ public class SecurityMockServerConfigurers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class SetupMutatorFilter implements WebFilter {
|
private static class SetupMutatorFilter implements WebFilter {
|
||||||
private final Mono<SecurityContext> context;
|
private final Supplier<Mono<SecurityContext>> context;
|
||||||
|
|
||||||
private SetupMutatorFilter(Mono<SecurityContext> context) {
|
private SetupMutatorFilter(Supplier<Mono<SecurityContext>> context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SetupMutatorFilter(SecurityContext context) {
|
|
||||||
this(Mono.just(context));
|
|
||||||
}
|
|
||||||
|
|
||||||
private SetupMutatorFilter(Authentication authentication) {
|
|
||||||
this(new SecurityContextImpl(authentication));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain webFilterChain) {
|
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain webFilterChain) {
|
||||||
exchange.getAttributes().computeIfAbsent(MutatorFilter.ATTRIBUTE_NAME, key -> this.context);
|
exchange.getAttributes().computeIfAbsent(MutatorFilter.ATTRIBUTE_NAME, key -> this.context);
|
||||||
@ -273,11 +254,11 @@ public class SecurityMockServerConfigurers {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain webFilterChain) {
|
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain webFilterChain) {
|
||||||
Mono<SecurityContext> context = exchange.getAttribute(ATTRIBUTE_NAME);
|
Supplier<Mono<SecurityContext>> context = exchange.getAttribute(ATTRIBUTE_NAME);
|
||||||
if(context != null) {
|
if(context != null) {
|
||||||
exchange.getAttributes().remove(ATTRIBUTE_NAME);
|
exchange.getAttributes().remove(ATTRIBUTE_NAME);
|
||||||
return webFilterChain.filter(exchange)
|
return webFilterChain.filter(exchange)
|
||||||
.subscriberContext(ReactiveSecurityContextHolder.withSecurityContext(context));
|
.subscriberContext(ReactiveSecurityContextHolder.withSecurityContext(context.get()));
|
||||||
}
|
}
|
||||||
return webFilterChain.filter(exchange);
|
return webFilterChain.filter(exchange);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,16 +20,18 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.test.context.TestSecurityContextHolder;
|
import org.springframework.security.test.context.TestSecurityContextHolder;
|
||||||
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
|
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
|
||||||
import org.springframework.security.test.context.support.WithMockUser;
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
|
||||||
import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.mockPrincipal;
|
import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.mockAuthentication;
|
||||||
import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.springSecurity;
|
import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.springSecurity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,6 +44,7 @@ public class SecurityMockServerConfigurersAnnotatedTests extends AbstractMockSer
|
|||||||
|
|
||||||
WebTestClient client = WebTestClient
|
WebTestClient client = WebTestClient
|
||||||
.bindToController(controller)
|
.bindToController(controller)
|
||||||
|
.webFilter(new SecurityContextServerWebExchangeWebFilter())
|
||||||
.apply(springSecurity())
|
.apply(springSecurity())
|
||||||
.configureClient()
|
.configureClient()
|
||||||
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
||||||
@ -62,11 +65,12 @@ public class SecurityMockServerConfigurersAnnotatedTests extends AbstractMockSer
|
|||||||
@Test
|
@Test
|
||||||
@WithMockUser
|
@WithMockUser
|
||||||
public void withMockUserWhenGlobalMockPrincipalThenOverridesAnnotation() {
|
public void withMockUserWhenGlobalMockPrincipalThenOverridesAnnotation() {
|
||||||
Principal principal = () -> "principal";
|
TestingAuthenticationToken authentication = new TestingAuthenticationToken("authentication", "secret", "ROLE_USER");
|
||||||
client = WebTestClient
|
client = WebTestClient
|
||||||
.bindToController(controller)
|
.bindToController(controller)
|
||||||
|
.webFilter(new SecurityContextServerWebExchangeWebFilter())
|
||||||
.apply(springSecurity())
|
.apply(springSecurity())
|
||||||
.apply(mockPrincipal(principal))
|
.apply(mockAuthentication(authentication))
|
||||||
.configureClient()
|
.configureClient()
|
||||||
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
||||||
.build();
|
.build();
|
||||||
@ -76,33 +80,33 @@ public class SecurityMockServerConfigurersAnnotatedTests extends AbstractMockSer
|
|||||||
.exchange()
|
.exchange()
|
||||||
.expectStatus().isOk();
|
.expectStatus().isOk();
|
||||||
|
|
||||||
controller.assertPrincipalIsEqualTo(principal);
|
controller.assertPrincipalIsEqualTo(authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithMockUser
|
@WithMockUser
|
||||||
public void withMockUserWhenMutateWithMockPrincipalThenOverridesAnnotation() {
|
public void withMockUserWhenMutateWithMockPrincipalThenOverridesAnnotation() {
|
||||||
Principal principal = () -> "principal";
|
TestingAuthenticationToken authentication = new TestingAuthenticationToken("authentication", "secret", "ROLE_USER");
|
||||||
client
|
client
|
||||||
.mutateWith(mockPrincipal(principal))
|
.mutateWith(mockAuthentication(authentication))
|
||||||
.get()
|
.get()
|
||||||
.exchange()
|
.exchange()
|
||||||
.expectStatus().isOk();
|
.expectStatus().isOk();
|
||||||
|
|
||||||
controller.assertPrincipalIsEqualTo(principal);
|
controller.assertPrincipalIsEqualTo(authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithMockUser
|
@WithMockUser
|
||||||
public void withMockUserWhenMutateWithMockPrincipalAndNoMutateThenOverridesAnnotationAndUsesAnnotation() {
|
public void withMockUserWhenMutateWithMockPrincipalAndNoMutateThenOverridesAnnotationAndUsesAnnotation() {
|
||||||
Principal principal = () -> "principal";
|
TestingAuthenticationToken authentication = new TestingAuthenticationToken("authentication", "secret", "ROLE_USER");
|
||||||
client
|
client
|
||||||
.mutateWith(mockPrincipal(principal))
|
.mutateWith(mockAuthentication(authentication))
|
||||||
.get()
|
.get()
|
||||||
.exchange()
|
.exchange()
|
||||||
.expectStatus().isOk();
|
.expectStatus().isOk();
|
||||||
|
|
||||||
controller.assertPrincipalIsEqualTo(principal);
|
controller.assertPrincipalIsEqualTo(authentication);
|
||||||
|
|
||||||
|
|
||||||
client
|
client
|
||||||
@ -110,7 +114,6 @@ public class SecurityMockServerConfigurersAnnotatedTests extends AbstractMockSer
|
|||||||
.exchange()
|
.exchange()
|
||||||
.expectStatus().isOk();
|
.expectStatus().isOk();
|
||||||
|
|
||||||
principal = controller.removePrincipal();
|
assertPrincipalCreatedFromUserDetails(controller.removePrincipal(), userBuilder.build());
|
||||||
assertPrincipalCreatedFromUserDetails(principal, userBuilder.build());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import org.springframework.security.core.Authentication;
|
|||||||
import org.springframework.security.test.context.TestSecurityContextHolder;
|
import org.springframework.security.test.context.TestSecurityContextHolder;
|
||||||
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
|
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
|
||||||
import org.springframework.security.test.context.support.WithMockUser;
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
|
||||||
@ -43,6 +44,7 @@ import static org.springframework.security.test.web.reactive.server.SecurityMock
|
|||||||
public class SecurityMockServerConfigurersClassAnnotatedTests extends AbstractMockServerConfigurersTests {
|
public class SecurityMockServerConfigurersClassAnnotatedTests extends AbstractMockServerConfigurersTests {
|
||||||
WebTestClient client = WebTestClient
|
WebTestClient client = WebTestClient
|
||||||
.bindToController(controller)
|
.bindToController(controller)
|
||||||
|
.webFilter(new SecurityContextServerWebExchangeWebFilter())
|
||||||
.apply(springSecurity())
|
.apply(springSecurity())
|
||||||
.configureClient()
|
.configureClient()
|
||||||
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import org.springframework.http.MediaType;
|
|||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.core.userdetails.User;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter;
|
||||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
@ -35,55 +36,12 @@ import static org.springframework.security.test.web.reactive.server.SecurityMock
|
|||||||
public class SecurityMockServerConfigurersTests extends AbstractMockServerConfigurersTests {
|
public class SecurityMockServerConfigurersTests extends AbstractMockServerConfigurersTests {
|
||||||
WebTestClient client = WebTestClient
|
WebTestClient client = WebTestClient
|
||||||
.bindToController(controller)
|
.bindToController(controller)
|
||||||
|
.webFilter(new SecurityContextServerWebExchangeWebFilter())
|
||||||
.apply(springSecurity())
|
.apply(springSecurity())
|
||||||
.configureClient()
|
.configureClient()
|
||||||
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@Test
|
|
||||||
public void mockPrincipalWhenLocalThenSuccess() {
|
|
||||||
Principal principal = () -> "principal";
|
|
||||||
client
|
|
||||||
.mutateWith(mockPrincipal(principal))
|
|
||||||
.get()
|
|
||||||
.exchange()
|
|
||||||
.expectStatus().isOk();
|
|
||||||
|
|
||||||
controller.assertPrincipalIsEqualTo(principal);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void mockPrincipalWhenGlobalTheWorks() {
|
|
||||||
Principal principal = () -> "principal";
|
|
||||||
client = WebTestClient
|
|
||||||
.bindToController(controller)
|
|
||||||
.apply(springSecurity())
|
|
||||||
.apply(mockPrincipal(principal))
|
|
||||||
.configureClient()
|
|
||||||
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
client
|
|
||||||
.get()
|
|
||||||
.exchange()
|
|
||||||
.expectStatus().isOk();
|
|
||||||
|
|
||||||
controller.assertPrincipalIsEqualTo(principal);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void mockPrincipalWhenMultipleInvocationsThenLastInvocationWins() {
|
|
||||||
Principal principal = () -> "principal";
|
|
||||||
client
|
|
||||||
.mutateWith(mockPrincipal(() -> "will be overridden"))
|
|
||||||
.mutateWith(mockPrincipal(principal))
|
|
||||||
.get()
|
|
||||||
.exchange()
|
|
||||||
.expectStatus().isOk();
|
|
||||||
|
|
||||||
controller.assertPrincipalIsEqualTo(principal);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void mockAuthenticationWhenLocalThenSuccess() {
|
public void mockAuthenticationWhenLocalThenSuccess() {
|
||||||
TestingAuthenticationToken authentication = new TestingAuthenticationToken("authentication", "secret", "ROLE_USER");
|
TestingAuthenticationToken authentication = new TestingAuthenticationToken("authentication", "secret", "ROLE_USER");
|
||||||
@ -100,6 +58,7 @@ public class SecurityMockServerConfigurersTests extends AbstractMockServerConfig
|
|||||||
TestingAuthenticationToken authentication = new TestingAuthenticationToken("authentication", "secret", "ROLE_USER");
|
TestingAuthenticationToken authentication = new TestingAuthenticationToken("authentication", "secret", "ROLE_USER");
|
||||||
client = WebTestClient
|
client = WebTestClient
|
||||||
.bindToController(controller)
|
.bindToController(controller)
|
||||||
|
.webFilter(new SecurityContextServerWebExchangeWebFilter())
|
||||||
.apply(springSecurity())
|
.apply(springSecurity())
|
||||||
.apply(mockAuthentication(authentication))
|
.apply(mockAuthentication(authentication))
|
||||||
.configureClient()
|
.configureClient()
|
||||||
@ -129,6 +88,7 @@ public class SecurityMockServerConfigurersTests extends AbstractMockServerConfig
|
|||||||
public void mockUserWhenGlobalThenSuccess() {
|
public void mockUserWhenGlobalThenSuccess() {
|
||||||
client = WebTestClient
|
client = WebTestClient
|
||||||
.bindToController(controller)
|
.bindToController(controller)
|
||||||
|
.webFilter(new SecurityContextServerWebExchangeWebFilter())
|
||||||
.apply(springSecurity())
|
.apply(springSecurity())
|
||||||
.apply(mockUser())
|
.apply(mockUser())
|
||||||
.configureClient()
|
.configureClient()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user