WebTestClient 在使用 SpringBootTest 的 random_port 模式下运行时支持 HTTPS。

huangapple go评论75阅读模式
英文:

WebTestClient on HTTPS with SpringBootTest random_port

问题

根据您提供的代码片段和问题描述,您想要配置WebTestClient在使用AutoConfigureWebTestClient时使用HTTPS协议,并解决端口和证书的问题。以下是您可能需要的部分翻译:

我有一个用于实现TLSv1.3 over HTTPS的REST服务在我的应用程序中禁止使用HTTP)。现在测试失败因为WebTestClient使用HTTP协议而不是HTTPS协议进行调用我知道我可以自己构建WebTestClient但为了增加趣味性这些测试使用RANDOM_PORT因为CI作业在共享不同团队的单个Jenkins节点上运行我不能安全地删除它)。

根据应用程序日志我可以看到WebTestClient正在调用我的服务

GET http://localhost:19654/health-check

这之前运行正常但现在应该使用HTTPS我是否可以配置WebTestClient在使用AutoConfigureWebTestClient时使用HTTPS或者如何配置WebTestClient以适应Spring设置的RANDOM_PORT

@Update
这是我已经尝试过的

private WebTestClient webTestClient;

@PostConstruct
void init() throws SSLException {
    // var sslContext = SSLContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build;
    // var httpClient = HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
    webTestClient = WebTestClient.bindToServer().baseUrl("https://localhost:<fix_port>").build()
}

这在某种程度上是有效的请求通过HTTPS发送但问题是如何从WebEnvironment获取端口以及显然不正确的证书虽然WebClient具有可以配置httpClient的clientConnector但我似乎找不到WebTestClient的等效部分

@Update2
我成功配置了WebTestClient的SSLContext唯一的问题是只有在硬编码端口的情况下才能这样做

@PostConstruct
void init() throws SSLException {
    var sslContext = SSLContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build;
    var httpClient = HttpClient.create().secure(sslContextSpec -&gt; sslContextSpec.sslContext(sslContext));
    webTestClient = WebTestClient.bindToServer(new ReactorClientHttpConnector(httpClient)).baseUrl("https://localhost:<fixed-port>").build();
}

请注意,您需要将<fix_port><fixed-port>替换为实际的端口号。希望这有助于解决您的问题。

英文:

I have a rest service for which I needed to implement TLSv1.3 over HTTPS (HTTP is prohibited at my place for this app). Now the tests are failing because WebTestClient is making calls using http protocol over https. I know I could build WebTestClient myself, but to make things more interesting these tests are using RANDOM_PORT because the CI jobs are running on a single jenkins node that's shared across different teams (I cannot remove it safely).

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = &quot;spring.main.allow-bean-definition-overriding=true&quot;)
@ContextConfiguration(classes = TestWebClientConfiguration.class)  // contains beans to connect to mocked downstream services
@TestMethodOrder(MethodOrdeded.OrderAnnotation.class)
@DirtiesContext
@AutoConfigureWebTestClient
@ActiveProfiles(value = {&quot;test&quot;})
public class HealthCheckTests {
    @Autowired
    private WebTestClient webTestClient;
    ...
}

Based on the application logs I can see that webTestClient is making calls to my service like:

GET http://localhost:19654/health-check

which was working fine, but now it should be https. Can I configure WebTestClient to use HTTPS while using AutoConfigureWebTestClient, alternatively how can I configure WebTestClient towards to RANDOM_PORT that spring sets.

@Update
Here's what I have tried already:

private WebTestClient webTestClient;

@PostConstruct
void init() throws SSLException {
    // var sslContext = SSLContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build;
    // var httpClient = HttpClient.create().secure(sslContextSpec -&gt; sslContextSpec.sslContext(sslContext));
    webTestClient = WebTestClient.bindToServer().baseUrl(&quot;https://localhost:&lt;fix_port&gt;&quot;).build()
}

This works to some degree. The requests are sent over HTTPS the issues are getting the port from WebEnvironment, and obviously the incorrect certificates. While WebClient has clientConnector where httpClient can be configured, I cannot seem to find the equivalent to this for WebTestClient.

@Update2:
I managed to configure the SSLContext with the WebTestClient, the only issue that remains is that I can only do it if I'm hardcoding the port.

@PostConstruct
void init() throws SSLException {
    var sslContext = SSLContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build;
    var httpClient = HttpClient.create().secure(sslContextSpec -&gt; sslContextSpec.sslContext(sslContext));
    webTestClient = WebTestClient.bindToServer(new ReactorClientHttpConnector(httpClient)).baseUrl(&quot;https://localhost:&lt;fixed-port&gt;&quot;).build();
}

答案1

得分: 0

不是一个优雅的解决方案但我设法使其工作但不是使用 @AuthConfigureWebTestClient最终解决方案如下

    @LocalServerPort
    private int port;

    private WebTestClient webTestClient;

    @PostConstruct
    void init() throws SSLException {
        var sslContext = SSLContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build;
        var httpClient = HttpClient.create().secure(sslContextSpec -&gt; sslContextSpec.sslContext(sslContext));
        webTestClient = WebTestClient.bindToServer(new ReactorClientHttpConnector(httpClient)).baseUrl(&quot;https://localhost:%d&quot;.formatted(port)).build();
    }
英文:

Not an elegant solution, but I managed to get it working, but not with @AuthConfigureWebTestClient. The final solution was the below:

@LocalServerPort
private int port;

private WebTestClient webTestClient;

@PostConstruct
void init() throws SSLException {
    var sslContext = SSLContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build;
    var httpClient = HttpClient.create().secure(sslContextSpec -&gt; sslContextSpec.sslContext(sslContext));
    webTestClient = WebTestClient.bindToServer(new ReactorClientHttpConnector(httpClient)).baseUrl(&quot;https://localhost:%d&quot;.formatted(port)).build();
}

huangapple
  • 本文由 发表于 2023年6月21日 22:44:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76524555.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定