关闭 JiraRestClient 的 ssl 证书验证
Turn off ssl certificate validation for JiraRestClient
我正在尝试通过 atlassian rest api java 框架连接到我的 Jira:
JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
JiraRestClient client = factory.createWithBasicHttpAuthentication(uri, userName, password);
但这会导致错误:
javax.net.ssl.SSLHandshakeException: General SSLEngine problem
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
我认为发生这种情况是因为我为我的 Jira 使用了自签名证书。至少出于开发目的,有没有办法关闭 JiraRestClientFactory
的证书验证?
将您的 self-signed 证书添加到本地 JVM TrustStore 会更加谨慎。
不过,您可以通过使用 AsynchronousJiraRestClientFactory.create(URI, HttpClient)
方法创建客户端对象来禁用检查。应该可以提供您自己的 HttpClient
实例来禁用证书验证。 Atlassian 似乎用自定义工厂和装饰器重新打包了 Apache HttpClient 库,因此您必须深入研究 attlassian-httpclient-*
库源代码。
有 com.atlassian.httpclient.api.factory.HttpClientOptions#setTrustSelfSignedCertificates(boolean)
标志。应该可以创建自己的 AsynchronousHttpClientFactory#createClient(URI, AuthenticationHandler)
方法版本,其中当前创建了一个空的 HttpClientOptions
:
public DisposableHttpClient createClient(final URI serverUri, final AuthenticationHandler authenticationHandler) {
final HttpClientOptions options = new HttpClientOptions();
options.setTrustSelfSignedCertificates(true); // try this
您可以尝试以下方式。以下代码将跳过证书验证并使用 CloseableHTTPClient 实例访问 Jira rest API
private void getTicketDetails(URI url, String userid, String password)
throws NoSuchAlgorithmException, KeyManagementException {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException {
}
} };
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(url.getHost(), url.getPort()),
new UsernamePasswordCredentials(userid, password));
CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setSslcontext(sc).setDefaultCredentialsProvider(credsProvider).build();
JiraRestClient client = factory.create(url, (HttpClient) httpClient);
}
感谢您的回复!我最终得到的解决方案是基于 Karol Dowbeckis 的回答:
JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
HttpClientOptions options = new HttpClientOptions();
options.setTrustSelfSignedCertificates(true);
DefaultHttpClientFactory defaultHttpClientFactory = new DefaultHttpClientFactory(new NoOpEventPublisher(),
new RestClientApplicationProperties(JIRA_URI), new ThreadLocalContextManager() {
@Override
public Object getThreadLocalContext() {
return null;
}
@Override
public void setThreadLocalContext(Object context) {
}
@Override
public void clearThreadLocalContext() {
}
});
HttpClient httpClient = defaultHttpClientFactory.create(options);
AtlassianHttpClientDecorator atlassianHttpClientDecorator = new AtlassianHttpClientDecorator(httpClient, new BasicHttpAuthenticationHandler(userName, password)) {
@Override
public void destroy() throws Exception {
defaultHttpClientFactory.dispose(httpClient);
}
};
JiraRestClient client = factory.create(JIRA_URI, atlassianHttpClientDecorator);
我必须添加我自己的 NoOpEventPublisher
和 RestClientApplicationProperties
的简单实现,因为 atlassian 类 是私有的。
此代码示例的附加信息
- 此示例使用的是 jira rest 客户端版本 4.0.0
NoOpEventPublisher
只是 com.atlassian.event.api.EventPublisher
的一个实现,方法体为空。
RestClientApplicationProperties
实现 com.atlassian.sal.api.ApplicationProperties
在 getBaseUrl
中返回我的 jira url 并在 getVersion
中返回“4.0.0”
我知道您在寻找不使用信任库的解决方案。但是现在您的系统将只信任任何证书,并且在生产环境中部署时您将不得不禁用您的解决方法。
我建议建议以下解决方案:
如您所见 - 这是由于您的自签名 ssl 证书未在信任库中注册造成的。但是,与其信任所有证书,不如将您自己签名的证书添加到 java 信任库中。解决起来简单快捷。
keytool -genkeypair -alias alias_name -keyalg RSA -validity #_of_days -keysize 2048 -keystore path_to_keystore_file
默认信任库位于
{JAVA_HOME}/jre/lib/security/cacerts
您还可以创建自定义信任库,并在启动应用程序时将路径作为参数传递。
可以在此处找到有关信任存储的更多信息和示例:
https://docs.oracle.com/cd/E54932_01/doc.705/e54936/cssg_create_ssl_cert.htm#CSVSG178
我正在尝试通过 atlassian rest api java 框架连接到我的 Jira:
JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
JiraRestClient client = factory.createWithBasicHttpAuthentication(uri, userName, password);
但这会导致错误:
javax.net.ssl.SSLHandshakeException: General SSLEngine problem
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
我认为发生这种情况是因为我为我的 Jira 使用了自签名证书。至少出于开发目的,有没有办法关闭 JiraRestClientFactory
的证书验证?
将您的 self-signed 证书添加到本地 JVM TrustStore 会更加谨慎。
不过,您可以通过使用 AsynchronousJiraRestClientFactory.create(URI, HttpClient)
方法创建客户端对象来禁用检查。应该可以提供您自己的 HttpClient
实例来禁用证书验证。 Atlassian 似乎用自定义工厂和装饰器重新打包了 Apache HttpClient 库,因此您必须深入研究 attlassian-httpclient-*
库源代码。
有 com.atlassian.httpclient.api.factory.HttpClientOptions#setTrustSelfSignedCertificates(boolean)
标志。应该可以创建自己的 AsynchronousHttpClientFactory#createClient(URI, AuthenticationHandler)
方法版本,其中当前创建了一个空的 HttpClientOptions
:
public DisposableHttpClient createClient(final URI serverUri, final AuthenticationHandler authenticationHandler) {
final HttpClientOptions options = new HttpClientOptions();
options.setTrustSelfSignedCertificates(true); // try this
您可以尝试以下方式。以下代码将跳过证书验证并使用 CloseableHTTPClient 实例访问 Jira rest API
private void getTicketDetails(URI url, String userid, String password)
throws NoSuchAlgorithmException, KeyManagementException {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
throws CertificateException {
}
} };
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(url.getHost(), url.getPort()),
new UsernamePasswordCredentials(userid, password));
CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setSslcontext(sc).setDefaultCredentialsProvider(credsProvider).build();
JiraRestClient client = factory.create(url, (HttpClient) httpClient);
}
感谢您的回复!我最终得到的解决方案是基于 Karol Dowbeckis 的回答:
JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
HttpClientOptions options = new HttpClientOptions();
options.setTrustSelfSignedCertificates(true);
DefaultHttpClientFactory defaultHttpClientFactory = new DefaultHttpClientFactory(new NoOpEventPublisher(),
new RestClientApplicationProperties(JIRA_URI), new ThreadLocalContextManager() {
@Override
public Object getThreadLocalContext() {
return null;
}
@Override
public void setThreadLocalContext(Object context) {
}
@Override
public void clearThreadLocalContext() {
}
});
HttpClient httpClient = defaultHttpClientFactory.create(options);
AtlassianHttpClientDecorator atlassianHttpClientDecorator = new AtlassianHttpClientDecorator(httpClient, new BasicHttpAuthenticationHandler(userName, password)) {
@Override
public void destroy() throws Exception {
defaultHttpClientFactory.dispose(httpClient);
}
};
JiraRestClient client = factory.create(JIRA_URI, atlassianHttpClientDecorator);
我必须添加我自己的 NoOpEventPublisher
和 RestClientApplicationProperties
的简单实现,因为 atlassian 类 是私有的。
此代码示例的附加信息
- 此示例使用的是 jira rest 客户端版本 4.0.0
NoOpEventPublisher
只是com.atlassian.event.api.EventPublisher
的一个实现,方法体为空。RestClientApplicationProperties
实现com.atlassian.sal.api.ApplicationProperties
在getBaseUrl
中返回我的 jira url 并在getVersion
中返回“4.0.0”
我知道您在寻找不使用信任库的解决方案。但是现在您的系统将只信任任何证书,并且在生产环境中部署时您将不得不禁用您的解决方法。
我建议建议以下解决方案:
如您所见 - 这是由于您的自签名 ssl 证书未在信任库中注册造成的。但是,与其信任所有证书,不如将您自己签名的证书添加到 java 信任库中。解决起来简单快捷。
keytool -genkeypair -alias alias_name -keyalg RSA -validity #_of_days -keysize 2048 -keystore path_to_keystore_file
默认信任库位于
{JAVA_HOME}/jre/lib/security/cacerts
您还可以创建自定义信任库,并在启动应用程序时将路径作为参数传递。
可以在此处找到有关信任存储的更多信息和示例:
https://docs.oracle.com/cd/E54932_01/doc.705/e54936/cssg_create_ssl_cert.htm#CSVSG178