mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Merge branch '3.0.x' into 3.1.x
Closes gh-38365
This commit is contained in:
commit
37b2567aeb
@ -75,22 +75,23 @@ import static org.mockito.Mockito.mock;
|
|||||||
*/
|
*/
|
||||||
class CloudFoundryWebFluxEndpointIntegrationTests {
|
class CloudFoundryWebFluxEndpointIntegrationTests {
|
||||||
|
|
||||||
private static final ReactiveTokenValidator tokenValidator = mock(ReactiveTokenValidator.class);
|
private final ReactiveTokenValidator tokenValidator = mock(ReactiveTokenValidator.class);
|
||||||
|
|
||||||
private static final ReactiveCloudFoundrySecurityService securityService = mock(
|
private final ReactiveCloudFoundrySecurityService securityService = mock(ReactiveCloudFoundrySecurityService.class);
|
||||||
ReactiveCloudFoundrySecurityService.class);
|
|
||||||
|
|
||||||
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner(
|
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner(
|
||||||
AnnotationConfigReactiveWebServerApplicationContext::new)
|
AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||||
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class,
|
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class,
|
||||||
ReactiveWebServerFactoryAutoConfiguration.class))
|
ReactiveWebServerFactoryAutoConfiguration.class))
|
||||||
.withUserConfiguration(TestEndpointConfiguration.class)
|
.withUserConfiguration(TestEndpointConfiguration.class)
|
||||||
|
.withBean(ReactiveTokenValidator.class, () -> this.tokenValidator)
|
||||||
|
.withBean(ReactiveCloudFoundrySecurityService.class, () -> this.securityService)
|
||||||
.withPropertyValues("server.port=0");
|
.withPropertyValues("server.port=0");
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void operationWithSecurityInterceptorForbidden() {
|
void operationWithSecurityInterceptorForbidden() {
|
||||||
given(tokenValidator.validate(any())).willReturn(Mono.empty());
|
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
|
||||||
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
|
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
|
||||||
this.contextRunner.run(withWebTestClient((client) -> client.get()
|
this.contextRunner.run(withWebTestClient((client) -> client.get()
|
||||||
.uri("/cfApplication/test")
|
.uri("/cfApplication/test")
|
||||||
.accept(MediaType.APPLICATION_JSON)
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
@ -102,8 +103,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void operationWithSecurityInterceptorSuccess() {
|
void operationWithSecurityInterceptorSuccess() {
|
||||||
given(tokenValidator.validate(any())).willReturn(Mono.empty());
|
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
|
||||||
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
|
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
|
||||||
this.contextRunner.run(withWebTestClient((client) -> client.get()
|
this.contextRunner.run(withWebTestClient((client) -> client.get()
|
||||||
.uri("/cfApplication/test")
|
.uri("/cfApplication/test")
|
||||||
.accept(MediaType.APPLICATION_JSON)
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
@ -131,8 +132,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void linksToOtherEndpointsWithFullAccess() {
|
void linksToOtherEndpointsWithFullAccess() {
|
||||||
given(tokenValidator.validate(any())).willReturn(Mono.empty());
|
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
|
||||||
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
|
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
|
||||||
this.contextRunner.run(withWebTestClient((client) -> client.get()
|
this.contextRunner.run(withWebTestClient((client) -> client.get()
|
||||||
.uri("/cfApplication")
|
.uri("/cfApplication")
|
||||||
.accept(MediaType.APPLICATION_JSON)
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
@ -169,7 +170,7 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
|
|||||||
void linksToOtherEndpointsForbidden() {
|
void linksToOtherEndpointsForbidden() {
|
||||||
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
|
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
|
||||||
"invalid-token");
|
"invalid-token");
|
||||||
willThrow(exception).given(tokenValidator).validate(any());
|
willThrow(exception).given(this.tokenValidator).validate(any());
|
||||||
this.contextRunner.run(withWebTestClient((client) -> client.get()
|
this.contextRunner.run(withWebTestClient((client) -> client.get()
|
||||||
.uri("/cfApplication")
|
.uri("/cfApplication")
|
||||||
.accept(MediaType.APPLICATION_JSON)
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
@ -181,8 +182,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void linksToOtherEndpointsWithRestrictedAccess() {
|
void linksToOtherEndpointsWithRestrictedAccess() {
|
||||||
given(tokenValidator.validate(any())).willReturn(Mono.empty());
|
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
|
||||||
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
|
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
|
||||||
this.contextRunner.run(withWebTestClient((client) -> client.get()
|
this.contextRunner.run(withWebTestClient((client) -> client.get()
|
||||||
.uri("/cfApplication")
|
.uri("/cfApplication")
|
||||||
.accept(MediaType.APPLICATION_JSON)
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
@ -232,7 +233,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
|
|||||||
static class CloudFoundryReactiveConfiguration {
|
static class CloudFoundryReactiveConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
CloudFoundrySecurityInterceptor interceptor() {
|
CloudFoundrySecurityInterceptor interceptor(ReactiveTokenValidator tokenValidator,
|
||||||
|
ReactiveCloudFoundrySecurityService securityService) {
|
||||||
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id");
|
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
|||||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||||
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
|
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer;
|
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer;
|
||||||
|
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
@ -70,13 +71,13 @@ import static org.mockito.Mockito.mock;
|
|||||||
*/
|
*/
|
||||||
class CloudFoundryMvcWebEndpointIntegrationTests {
|
class CloudFoundryMvcWebEndpointIntegrationTests {
|
||||||
|
|
||||||
private static final TokenValidator tokenValidator = mock(TokenValidator.class);
|
private final TokenValidator tokenValidator = mock(TokenValidator.class);
|
||||||
|
|
||||||
private static final CloudFoundrySecurityService securityService = mock(CloudFoundrySecurityService.class);
|
private final CloudFoundrySecurityService securityService = mock(CloudFoundrySecurityService.class);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void operationWithSecurityInterceptorForbidden() {
|
void operationWithSecurityInterceptorForbidden() {
|
||||||
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
|
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
|
||||||
load(TestEndpointConfiguration.class,
|
load(TestEndpointConfiguration.class,
|
||||||
(client) -> client.get()
|
(client) -> client.get()
|
||||||
.uri("/cfApplication/test")
|
.uri("/cfApplication/test")
|
||||||
@ -89,7 +90,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void operationWithSecurityInterceptorSuccess() {
|
void operationWithSecurityInterceptorSuccess() {
|
||||||
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
|
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
|
||||||
load(TestEndpointConfiguration.class,
|
load(TestEndpointConfiguration.class,
|
||||||
(client) -> client.get()
|
(client) -> client.get()
|
||||||
.uri("/cfApplication/test")
|
.uri("/cfApplication/test")
|
||||||
@ -119,7 +120,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void linksToOtherEndpointsWithFullAccess() {
|
void linksToOtherEndpointsWithFullAccess() {
|
||||||
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
|
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
|
||||||
load(TestEndpointConfiguration.class,
|
load(TestEndpointConfiguration.class,
|
||||||
(client) -> client.get()
|
(client) -> client.get()
|
||||||
.uri("/cfApplication")
|
.uri("/cfApplication")
|
||||||
@ -157,7 +158,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
|
|||||||
void linksToOtherEndpointsForbidden() {
|
void linksToOtherEndpointsForbidden() {
|
||||||
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
|
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
|
||||||
"invalid-token");
|
"invalid-token");
|
||||||
willThrow(exception).given(tokenValidator).validate(any());
|
willThrow(exception).given(this.tokenValidator).validate(any());
|
||||||
load(TestEndpointConfiguration.class,
|
load(TestEndpointConfiguration.class,
|
||||||
(client) -> client.get()
|
(client) -> client.get()
|
||||||
.uri("/cfApplication")
|
.uri("/cfApplication")
|
||||||
@ -170,7 +171,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void linksToOtherEndpointsWithRestrictedAccess() {
|
void linksToOtherEndpointsWithRestrictedAccess() {
|
||||||
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
|
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
|
||||||
load(TestEndpointConfiguration.class,
|
load(TestEndpointConfiguration.class,
|
||||||
(client) -> client.get()
|
(client) -> client.get()
|
||||||
.uri("/cfApplication")
|
.uri("/cfApplication")
|
||||||
@ -198,26 +199,23 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
|
|||||||
.doesNotExist());
|
.doesNotExist());
|
||||||
}
|
}
|
||||||
|
|
||||||
private AnnotationConfigServletWebServerApplicationContext createApplicationContext(Class<?>... config) {
|
private void load(Class<?> configuration, Consumer<WebTestClient> clientConsumer) {
|
||||||
return new AnnotationConfigServletWebServerApplicationContext(config);
|
BiConsumer<ApplicationContext, WebTestClient> consumer = (context, client) -> clientConsumer.accept(client);
|
||||||
|
new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
|
||||||
|
.withUserConfiguration(configuration, CloudFoundryMvcConfiguration.class)
|
||||||
|
.withBean(TokenValidator.class, () -> this.tokenValidator)
|
||||||
|
.withBean(CloudFoundrySecurityService.class, () -> this.securityService)
|
||||||
|
.run((context) -> consumer.accept(context, WebTestClient.bindToServer()
|
||||||
|
.baseUrl("http://localhost:" + getPort(
|
||||||
|
(AnnotationConfigServletWebServerApplicationContext) context.getSourceApplicationContext()))
|
||||||
|
.responseTimeout(Duration.ofMinutes(5))
|
||||||
|
.build()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getPort(AnnotationConfigServletWebServerApplicationContext context) {
|
private int getPort(AnnotationConfigServletWebServerApplicationContext context) {
|
||||||
return context.getWebServer().getPort();
|
return context.getWebServer().getPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(Class<?> configuration, Consumer<WebTestClient> clientConsumer) {
|
|
||||||
BiConsumer<ApplicationContext, WebTestClient> consumer = (context, client) -> clientConsumer.accept(client);
|
|
||||||
try (AnnotationConfigServletWebServerApplicationContext context = createApplicationContext(configuration,
|
|
||||||
CloudFoundryMvcConfiguration.class)) {
|
|
||||||
consumer.accept(context,
|
|
||||||
WebTestClient.bindToServer()
|
|
||||||
.baseUrl("http://localhost:" + getPort(context))
|
|
||||||
.responseTimeout(Duration.ofMinutes(5))
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String mockAccessToken() {
|
private String mockAccessToken() {
|
||||||
return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwu"
|
return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwu"
|
||||||
+ "Y29tIiwiZXhwIjoxNDI2NDIwODAwLCJhd2Vzb21lIjp0cnVlfQ."
|
+ "Y29tIiwiZXhwIjoxNDI2NDIwODAwLCJhd2Vzb21lIjp0cnVlfQ."
|
||||||
@ -229,7 +227,8 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
|
|||||||
static class CloudFoundryMvcConfiguration {
|
static class CloudFoundryMvcConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
CloudFoundrySecurityInterceptor interceptor() {
|
CloudFoundrySecurityInterceptor interceptor(TokenValidator tokenValidator,
|
||||||
|
CloudFoundrySecurityService securityService) {
|
||||||
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id");
|
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user