Я пытаюсь подключиться к моей Jira через Java-среду atlassian rest api:

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 хотя бы для целей разработки?

0
Sebastian 4 Мар 2018 в 22:39

4 ответа

Лучший ответ

Спасибо за ответы! Решение, которое я выбрал, основано на ответе Кароля Доубекиса:

    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 являются частными.

1
Sebastian 13 Мар 2018 в 13:33

Было бы разумнее добавить самозаверяющий сертификат в локальный 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
1
Karol Dowbecki 11 Мар 2018 в 19:48

Я знаю, что вы искали решение, не используя хранилище доверия. Но теперь ваша система будет доверять любому сертификату, и вам придется отключить обходной путь при развертывании в продуктивной среде.

Я рекомендую предложить следующее решение:

Как вы заметили - это было вызвано тем, что ваш самоподписанный 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

1
Goot 15 Авг 2019 в 14:14

Вы можете попробовать следующий способ. Следующий код пропустит проверку сертификата и использует экземпляр CloseableHTTPClient, чтобы поразить API отдыха Jira.

    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);
}
1
Chids 12 Мар 2018 в 09:10