JSR223 Sampler中SSL证书错误,如何禁用证书校验?
如何在JSR223 Sampler的Apache HttpClient代码中禁用SSL证书校验?
没问题,你遇到的这个PKIX path building failed错误是因为HttpClient默认会严格验证目标服务器的SSL证书合法性——当证书是自签名、未被JVM信任的测试证书时,就会抛出这个异常。我们确实可以通过配置HttpClient来跳过证书校验,但必须先提醒你:这种做法只适合测试场景,绝对不能用在生产环境,它会彻底关闭SSL的安全验证,让你的请求完全暴露在中间人攻击的风险下。
下面是修改后的完整代码,我已经添加了禁用SSL校验的逻辑,你可以直接替换原来的代码使用:
import org.apache.http.HttpHeaders; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; import org.apache.http.entity.StringEntity; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.ssl.SSLContextBuilder; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.security.cert.X509Certificate; // 创建信任所有证书的TrustManager实现 TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) {} public void checkServerTrusted(X509Certificate[] certs, String authType) {} } }; List<String> sendRequest(String url, String method, String body) { RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(2000) .setSocketTimeout(3000) .build(); StringEntity entity = new StringEntity(body, "UTF-8"); HttpUriRequest request = RequestBuilder.create(method) .setConfig(requestConfig) .setUri(url) .setHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=UTF-8") .setEntity(entity) .build(); String req = "REQUEST:" + "\n" + request.getRequestLine() + "\n" + "Headers: " + request.getAllHeaders() + "\n" + EntityUtils.toString(entity) + "\n"; // 构建忽略证书校验的SSL上下文 def sslContext = SSLContextBuilder.create() .loadTrustMaterial(null, (chain, authType) -> true) .build(); // 创建跳过主机名校验的Socket工厂(避免"hostname不匹配"错误) SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory( sslContext, NoopHostnameVerifier.INSTANCE); // 让HttpClient使用这个不安全的SSL配置 HttpClientBuilder.create() .setSSLSocketFactory(sslSocketFactory) .build() .withCloseable {httpClient -> httpClient.execute(request).withCloseable {response -> String res = "RESPONSE:" + "\n" + response.getStatusLine() + "\n" + "Headers: " + response.getAllHeaders() + "\n" + (response.getEntity() != null ? EntityUtils.toString(response.getEntity()) : "") + "\n"; System.out.println(req + "\n" + res ); return Arrays.asList(req, res); } } } List test1 = sendRequest("https://testserver.com","POST", ""); log.info(Arrays.toString(test1));
关键修改点说明:
- 新增了
X509TrustManager实现,它会无条件信任所有服务器证书,不管其是否合法 - 通过
SSLContextBuilder构建了一个忽略证书校验的SSL上下文 - 使用
NoopHostnameVerifier跳过主机名与证书域名的匹配校验(避免额外的"hostname in certificate didn't match"错误) - 将自定义的SSL配置注入到
HttpClientBuilder中,让HttpClient使用这个不安全的配置
再次严肃提醒:生产环境绝对不要这么做!如果生产环境遇到证书信任问题,正确的做法是把服务器的CA证书导入到JVM的信任存储中,或者在HttpClient中单独配置信任该证书,而不是直接禁用所有校验。
内容的提问来源于stack exchange,提问作者user1829449
相关产品推荐
相关产品推荐

