代码之家  ›  专栏  ›  技术社区  ›  Sebastian

关闭JiraRestClient的ssl证书验证

  •  0
  • Sebastian  · 技术社区  · 7 年前

    我正试图通过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 至少是为了发展?

    4 回复  |  直到 7 年前
        1
  •  1
  •   Karol Dowbecki    7 年前

    更谨慎的做法是将自签名证书添加到本地JVM信任库中。

    但是,您可能可以通过使用创建客户端对象来禁用检查 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
    
        2
  •  1
  •   CGS    7 年前

    您可以尝试以下方法。以下代码将跳过证书验证,并使用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);
    }
    
        3
  •  1
  •   Lama    6 年前

    我知道您在哪里寻找解决方案而不使用信任存储。但现在,您的系统将只信任任何证书,并且在生产环境中部署时,您必须禁用变通方法。

    我建议采用以下解决方案:

    正如您所注意到的,这是由于您的自签名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

        4
  •  1
  •   Sebastian    5 年前

    感谢您的回复!我最终得出的解决方案基于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 正在返回我的jira url getBaseUrl 和中的“4.0.0” getVersion