英文:
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 -> 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 = "spring.main.allow-bean-definition-overriding=true")
@ContextConfiguration(classes = TestWebClientConfiguration.class) // contains beans to connect to mocked downstream services
@TestMethodOrder(MethodOrdeded.OrderAnnotation.class)
@DirtiesContext
@AutoConfigureWebTestClient
@ActiveProfiles(value = {"test"})
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 -> sslContextSpec.sslContext(sslContext));
webTestClient = WebTestClient.bindToServer().baseUrl("https://localhost:<fix_port>").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 -> sslContextSpec.sslContext(sslContext));
webTestClient = WebTestClient.bindToServer(new ReactorClientHttpConnector(httpClient)).baseUrl("https://localhost:<fixed-port>").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 -> sslContextSpec.sslContext(sslContext));
webTestClient = WebTestClient.bindToServer(new ReactorClientHttpConnector(httpClient)).baseUrl("https://localhost:%d".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 -> sslContextSpec.sslContext(sslContext));
webTestClient = WebTestClient.bindToServer(new ReactorClientHttpConnector(httpClient)).baseUrl("https://localhost:%d".formatted(port)).build();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论