关闭 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);

我必须添加我自己的 NoOpEventPublisherRestClientApplicationProperties 的简单实现,因为 atlassian 类 是私有的。

此代码示例的附加信息

  • 此示例使用的是 jira rest 客户端版本 4.0.0
  • NoOpEventPublisher 只是 com.atlassian.event.api.EventPublisher 的一个实现,方法体为空。
  • RestClientApplicationProperties 实现 com.atlassian.sal.api.ApplicationPropertiesgetBaseUrl 中返回我的 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