mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-09-17 12:09:16 +00:00
Return 503 for missing application ID or cloud controller URL
Previously, the CloudFoundryAuthorizationExceptions thrown for a missing application ID or cloud controller URL were not routed through the error handling that turned them into a SecurityResponse with a 503 status code. As a result, they were processed by the general exception handling which resulted in a 500 response. This commit updates the reactive SecurityInterceptor so that the exceptions are processed through SecurityInterceptor::getErrorResponse. This aligns the behavior of the Cloud Foundry security intergration in a reactive application more closely with that of a Servlet application. Fixes gh-51613
This commit is contained in:
+6
-3
@@ -59,10 +59,13 @@ class SecurityInterceptor {
|
||||
}
|
||||
|
||||
Mono<SecurityResponse> preHandle(ServerWebExchange exchange, String id) {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
if (CorsUtils.isPreFlightRequest(request)) {
|
||||
if (CorsUtils.isPreFlightRequest(exchange.getRequest())) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return doPreHandle(exchange, id).doOnError(this::logError).onErrorResume(this::getErrorResponse);
|
||||
}
|
||||
|
||||
private Mono<SecurityResponse> doPreHandle(ServerWebExchange exchange, String id) {
|
||||
if (!StringUtils.hasText(this.applicationId)) {
|
||||
return Mono.error(new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,
|
||||
"Application id is not available"));
|
||||
@@ -71,7 +74,7 @@ class SecurityInterceptor {
|
||||
return Mono.error(new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,
|
||||
"Cloud controller URL is not available"));
|
||||
}
|
||||
return check(exchange, id).then(SUCCESS).doOnError(this::logError).onErrorResume(this::getErrorResponse);
|
||||
return check(exchange, id).then(SUCCESS);
|
||||
}
|
||||
|
||||
private void logError(Throwable ex) {
|
||||
|
||||
+10
-7
@@ -28,7 +28,6 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.boot.cloudfoundry.autoconfigure.actuate.endpoint.AccessLevel;
|
||||
import org.springframework.boot.cloudfoundry.autoconfigure.actuate.endpoint.CloudFoundryAuthorizationException;
|
||||
import org.springframework.boot.cloudfoundry.autoconfigure.actuate.endpoint.CloudFoundryAuthorizationException.Reason;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -100,9 +99,11 @@ class SecurityInterceptorTests {
|
||||
.header(HttpHeaders.AUTHORIZATION, "bearer " + mockAccessToken())
|
||||
.build());
|
||||
StepVerifier.create(this.interceptor.preHandle(request, "/a"))
|
||||
.consumeErrorWith((ex) -> assertThat(((CloudFoundryAuthorizationException) ex).getReason())
|
||||
.isEqualTo(Reason.SERVICE_UNAVAILABLE))
|
||||
.verify();
|
||||
.consumeNextWith(
|
||||
(response) -> assertThat(response.getStatus()).isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus())
|
||||
.isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus()))
|
||||
.expectComplete()
|
||||
.verify(Duration.ofSeconds(30));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -111,9 +112,11 @@ class SecurityInterceptorTests {
|
||||
MockServerWebExchange request = MockServerWebExchange
|
||||
.from(MockServerHttpRequest.get("/a").header(HttpHeaders.AUTHORIZATION, mockAccessToken()).build());
|
||||
StepVerifier.create(this.interceptor.preHandle(request, "/a"))
|
||||
.consumeErrorWith((ex) -> assertThat(((CloudFoundryAuthorizationException) ex).getReason())
|
||||
.isEqualTo(Reason.SERVICE_UNAVAILABLE))
|
||||
.verify();
|
||||
.consumeNextWith(
|
||||
(response) -> assertThat(response.getStatus()).isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus())
|
||||
.isEqualTo(Reason.SERVICE_UNAVAILABLE.getStatus()))
|
||||
.expectComplete()
|
||||
.verify(Duration.ofSeconds(30));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user