Estoy tratando de conectarme a mi Jira a través del marco atlassian rest api java:

JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
JiraRestClient client = factory.createWithBasicHttpAuthentication(uri, userName, password);

Pero esto causa un error:

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

Creo que esto sucede porque uso un certificado autofirmado para mi Jira. ¿Hay alguna forma de desactivar la validación de certificados para JiraRestClientFactory al menos para fines de desarrollo?

0
Sebastian 4 mar. 2018 a las 22:39

4 respuestas

La mejor respuesta

Gracias por las respuestas! La solución con la que terminé se basa en la respuesta de 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);

Tuve que agregar mis propias implementaciones simples de NoOpEventPublisher y RestClientApplicationProperties porque las clases atlassian son privadas.

1
Sebastian 13 mar. 2018 a las 13:33

Sería más prudente agregar su certificado autofirmado a su JVM TrustStore local.

Sin embargo, probablemente pueda deshabilitar la verificación creando el objeto cliente con el método AsynchronousJiraRestClientFactory.create(URI, HttpClient). Debería ser posible proporcionar su propia instancia de HttpClient para deshabilitar la validación del certificado. Parece que Atlassian volvió a empaquetar la biblioteca Apache HttpClient con fábricas y decoradores personalizados, por lo que debe profundizar en el código fuente de las bibliotecas attlassian-httpclient-*.

Hay una bandera com.atlassian.httpclient.api.factory.HttpClientOptions#setTrustSelfSignedCertificates(boolean). Debería ser posible crear una versión propia del método AsynchronousHttpClientFactory#createClient(URI, AuthenticationHandler) donde actualmente se crea un HttpClientOptions vacío:

public DisposableHttpClient createClient(final URI serverUri, final AuthenticationHandler authenticationHandler) {
    final HttpClientOptions options = new HttpClientOptions();
    options.setTrustSelfSignedCertificates(true); // try this
1
Karol Dowbecki 11 mar. 2018 a las 19:48

Sé que buscabas una solución sin usar la tienda de confianza. Pero ahora su sistema confiará en cualquier certificado y tendrá que deshabilitar su solución alternativa al implementar en un entorno productivo.

Recomiendo sugerir la siguiente solución:

Como notó, esto fue causado por su certificado SSL autofirmado que no se registró en el almacén de confianza. Pero en lugar de confiar en todos los certificados, solo debe agregar su certificado auto-chamuscado a la tienda de confianza de Java. Es fácil y rápido de resolver.

keytool -genkeypair -alias alias_name -keyalg RSA -validity #_of_days -keysize 2048 -keystore path_to_keystore_file

El almacén de confianza predeterminado se puede encontrar en

{JAVA_HOME}/jre/lib/security/cacerts

También puede crear un almacén de confianza personalizado y pasar la ruta como parámetro al iniciar su aplicación.

Puede encontrar más información y ejemplos sobre tiendas de confianza aquí:

https://docs.oracle.com/cd/E54932_01/doc.705/e54936/cssg_create_ssl_cert.htm#CSVSG178

1
Goot 15 ago. 2019 a las 14:14

Puedes probar de la siguiente manera. El siguiente código omitirá la validación del certificado y usará una instancia de CloseableHTTPClient para acceder a la API de Jira rest

    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 mar. 2018 a las 09:10