Skip to content

Commit 09b3461

Browse files
committed
Remove use of self-signed.badssl.com
Closes gh-43708
1 parent 3c8e65c commit 09b3461

File tree

2 files changed

+63
-53
lines changed

2 files changed

+63
-53
lines changed

Diff for: spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfigurationTests.java

+63-53
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive;
1818

19+
import java.io.IOException;
1920
import java.time.Duration;
2021
import java.util.Arrays;
2122
import java.util.Collection;
@@ -24,6 +25,8 @@
2425

2526
import javax.net.ssl.SSLException;
2627

28+
import okhttp3.mockwebserver.MockResponse;
29+
import okhttp3.mockwebserver.MockWebServer;
2730
import org.junit.jupiter.api.AfterEach;
2831
import org.junit.jupiter.api.Test;
2932
import reactor.netty.http.HttpResources;
@@ -52,13 +55,19 @@
5255
import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration;
5356
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
5457
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration;
58+
import org.springframework.boot.ssl.SslBundle;
59+
import org.springframework.boot.ssl.jks.JksSslStoreBundle;
60+
import org.springframework.boot.ssl.jks.JksSslStoreDetails;
5561
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
62+
import org.springframework.boot.testsupport.classpath.resources.WithPackageResources;
5663
import org.springframework.boot.testsupport.classpath.resources.WithResource;
5764
import org.springframework.boot.web.reactive.function.client.WebClientCustomizer;
5865
import org.springframework.context.ApplicationContext;
5966
import org.springframework.context.annotation.Bean;
6067
import org.springframework.context.annotation.Configuration;
6168
import org.springframework.http.HttpMethod;
69+
import org.springframework.http.HttpStatusCode;
70+
import org.springframework.http.ResponseEntity;
6271
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
6372
import org.springframework.mock.web.server.MockServerWebExchange;
6473
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
@@ -78,6 +87,7 @@
7887
* Tests for {@link ReactiveCloudFoundryActuatorAutoConfiguration}.
7988
*
8089
* @author Madhura Bhave
90+
* @author Moritz Halbritter
8191
*/
8292
class ReactiveCloudFoundryActuatorAutoConfigurationTests {
8393

@@ -300,53 +310,63 @@ void gitFullDetailsAlwaysPresent() {
300310
}
301311

302312
@Test
303-
void skipSslValidation() {
304-
this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
305-
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
306-
"vcap.application.cf_api:https://my-cloud-controller.com",
307-
"management.cloudfoundry.skip-ssl-validation:true")
308-
.run((context) -> {
309-
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
310-
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
311-
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
312-
"cloudFoundrySecurityService");
313-
WebClient webClient = (WebClient) ReflectionTestUtils.getField(interceptorSecurityService, "webClient");
314-
doesNotFailWithSslException(() -> webClient.get()
315-
.uri("https://self-signed.badssl.com/")
316-
.retrieve()
317-
.toBodilessEntity()
318-
.block(Duration.ofSeconds(30)));
319-
});
320-
}
321-
322-
private static void doesNotFailWithSslException(Runnable action) {
323-
try {
324-
action.run();
325-
}
326-
catch (RuntimeException ex) {
327-
assertThat(findCause(ex, SSLException.class)).isNull();
313+
@WithPackageResources("test.jks")
314+
void skipSslValidation() throws IOException {
315+
JksSslStoreDetails keyStoreDetails = new JksSslStoreDetails("JKS", null, "classpath:test.jks", "secret");
316+
SslBundle sslBundle = SslBundle.of(new JksSslStoreBundle(keyStoreDetails, keyStoreDetails));
317+
try (MockWebServer server = new MockWebServer()) {
318+
server.useHttps(sslBundle.createSslContext().getSocketFactory(), false);
319+
server.enqueue(new MockResponse().setResponseCode(204));
320+
server.start();
321+
this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
322+
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
323+
"vcap.application.cf_api:https://my-cloud-controller.com",
324+
"management.cloudfoundry.skip-ssl-validation:true")
325+
.run((context) -> {
326+
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
327+
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
328+
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
329+
"cloudFoundrySecurityService");
330+
WebClient webClient = (WebClient) ReflectionTestUtils.getField(interceptorSecurityService,
331+
"webClient");
332+
ResponseEntity<Void> response = webClient.get()
333+
.uri(server.url("/").uri())
334+
.retrieve()
335+
.toBodilessEntity()
336+
.block(Duration.ofSeconds(30));
337+
assertThat(response.getStatusCode()).isEqualTo(HttpStatusCode.valueOf(204));
338+
});
328339
}
329340
}
330341

331342
@Test
332-
void sslValidationNotSkippedByDefault() {
333-
this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
334-
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
335-
"vcap.application.cf_api:https://my-cloud-controller.com")
336-
.run((context) -> {
337-
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
338-
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
339-
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
340-
"cloudFoundrySecurityService");
341-
WebClient webClient = (WebClient) ReflectionTestUtils.getField(interceptorSecurityService, "webClient");
342-
assertThatExceptionOfType(RuntimeException.class)
343-
.isThrownBy(() -> webClient.get()
344-
.uri("https://self-signed.badssl.com/")
345-
.retrieve()
346-
.toBodilessEntity()
347-
.block(Duration.ofSeconds(30)))
348-
.withCauseInstanceOf(SSLException.class);
349-
});
343+
@WithPackageResources("test.jks")
344+
void sslValidationNotSkippedByDefault() throws IOException {
345+
JksSslStoreDetails keyStoreDetails = new JksSslStoreDetails("JKS", null, "classpath:test.jks", "secret");
346+
SslBundle sslBundle = SslBundle.of(new JksSslStoreBundle(keyStoreDetails, keyStoreDetails));
347+
try (MockWebServer server = new MockWebServer()) {
348+
server.useHttps(sslBundle.createSslContext().getSocketFactory(), false);
349+
server.enqueue(new MockResponse().setResponseCode(204));
350+
server.start();
351+
this.contextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
352+
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
353+
"vcap.application.cf_api:https://my-cloud-controller.com")
354+
.run((context) -> {
355+
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping(context);
356+
Object interceptor = ReflectionTestUtils.getField(handlerMapping, "securityInterceptor");
357+
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
358+
"cloudFoundrySecurityService");
359+
WebClient webClient = (WebClient) ReflectionTestUtils.getField(interceptorSecurityService,
360+
"webClient");
361+
assertThatExceptionOfType(RuntimeException.class)
362+
.isThrownBy(() -> webClient.get()
363+
.uri(server.url("/").uri())
364+
.retrieve()
365+
.toBodilessEntity()
366+
.block(Duration.ofSeconds(30)))
367+
.withCauseInstanceOf(SSLException.class);
368+
});
369+
}
350370
}
351371

352372
private CloudFoundryWebFluxEndpointHandlerMapping getHandlerMapping(ApplicationContext context) {
@@ -365,16 +385,6 @@ private WebOperation findOperationWithRequestPath(ExposableWebEndpoint endpoint,
365385
"No operation found with request path " + requestPath + " from " + endpoint.getOperations());
366386
}
367387

368-
private static <E extends Throwable> E findCause(Throwable failure, Class<E> type) {
369-
while (failure != null) {
370-
if (type.isInstance(failure)) {
371-
return type.cast(failure);
372-
}
373-
failure = failure.getCause();
374-
}
375-
return null;
376-
}
377-
378388
@Endpoint(id = "test")
379389
static class TestEndpoint {
380390

0 commit comments

Comments
 (0)