Llamar a API internas que tienen certificados privados
Creado para:
- Experimentado
- Administrador
- Desarrollador
Aprenda a realizar llamadas HTTPS desde AEM a las API web mediante certificados privados o autofirmados.
De forma predeterminada, al intentar establecer una conexión HTTPS con una API web que utiliza un certificado firmado automáticamente, la conexión falla con el siguiente error:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Este problema suele ocurrir cuando el certificado SSL de la API no es emitido por una entidad de certificación (CA) reconocida y la aplicación Java™ no puede validar el certificado SSL/TLS.
Vamos a aprender a llamar correctamente a las API que tienen certificados privados o autofirmados mediante Apache HttpClient y TrustStore global de AEM.
Código de invocación de API prototípico mediante HttpClient
El siguiente código establece una conexión HTTPS con una API web:
...
String API_ENDPOINT = "https://example.com";
// Create HttpClientBuilder
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
// Create HttpClient
CloseableHttpClient httpClient = httpClientBuilder.build();
// Invoke API
CloseableHttpResponse closeableHttpResponse = httpClient.execute(new HttpGet(API_ENDPOINT));
// Code that reads response code and body from the 'closeableHttpResponse' object
...
El código usa las clases de biblioteca HttpClient de Apache HttpComponent y sus métodos.
HttpClient y cargar material de AEM TrustStore
Para llamar a un extremo de API que tiene certificado privado o autofirmado, HttpClient debe cargarse con TrustStore de AEM y usarse para facilitar la conexión.SSLContextBuilder
Siga estos pasos:
-
Inicie sesión en AEM Author como administrador.
-
Vaya a AEM Author > Herramientas > Seguridad > Almacén de confianza y abra el Almacén de confianza global. Si accede a la primera vez, establezca una contraseña para el Almacén de confianza global.
-
Para importar un certificado privado, haga clic en el botón Seleccionar archivo de certificado y seleccione el archivo de certificado deseado con la extensión
.cer
. Importarlo haciendo clic en el botón Enviar. -
Actualice el código Java™ como se muestra a continuación. Tenga en cuenta que para usar
@Reference
para obtenerKeyStoreService
de AEM, el código de llamada debe ser un componente o servicio OSGi o un modelo Sling (y@OsgiService
se usa allí).... // Get AEM's KeyStoreService reference @Reference private com.adobe.granite.keystore.KeyStoreService keyStoreService; ... // Get AEM TrustStore using KeyStoreService KeyStore aemTrustStore = getAEMTrustStore(keyStoreService, resourceResolver); if (aemTrustStore != null) { // Create SSL Context SSLContextBuilder sslbuilder = new SSLContextBuilder(); // Load AEM TrustStore material into above SSL Context sslbuilder.loadTrustMaterial(aemTrustStore, null); // Create SSL Connection Socket using above SSL Context SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslbuilder.build(), NoopHostnameVerifier.INSTANCE); // Create HttpClientBuilder HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); httpClientBuilder.setSSLSocketFactory(sslsf); // Create HttpClient CloseableHttpClient httpClient = httpClientBuilder.build(); // Invoke API closeableHttpResponse = httpClient.execute(new HttpGet(API_ENDPOINT)); // Code that reads response code and body from the 'closeableHttpResponse' object ... } /** * * Returns the global AEM TrustStore * * @param keyStoreService OOTB OSGi service that makes AEM based KeyStore * operations easy. * @param resourceResolver * @return */ private KeyStore getAEMTrustStore(KeyStoreService keyStoreService, ResourceResolver resourceResolver) { // get AEM TrustStore from the KeyStoreService and ResourceResolver KeyStore aemTrustStore = keyStoreService.getTrustStore(resourceResolver); return aemTrustStore; } ...
- Inserte el servicio OSGi OOTB
com.adobe.granite.keystore.KeyStoreService
en su componente OSGi. - Si se obtiene el almacén de confianza global de AEM mediante
KeyStoreService
yResourceResolver
, el métodogetAEMTrustStore(...)
lo hace. - Cree un objeto de
SSLContextBuilder
, consulte Java™ Detalles de la API. - Cargue el AEM TrustStore global en
SSLContextBuilder
mediante el métodoloadTrustMaterial(KeyStore truststore,TrustStrategy trustStrategy)
. - Pase
null
paraTrustStrategy
en el método anterior, se garantiza que solo los certificados de confianza de AEM se ejecuten correctamente durante la ejecución de la API.
- Inserte el servicio OSGi OOTB
Evitar cambios en el almacén de claves JVM
Un enfoque convencional para invocar de forma eficaz las API internas con certificados privados implica la modificación del repositorio de claves JVM. Se logra importando los certificados privados mediante el comando Java™ keytool.
Sin embargo, este método no está alineado con las prácticas recomendadas de seguridad y AEM ofrece una opción superior mediante el uso del Almacén de confianza global y KeyStoreService.
Paquete de soluciones
El proyecto Node.js de muestra que se muestra en el vídeo se puede descargar desde aquí.
El código de servlet de AEM está disponible en la rama tutorial/web-api-invocation
del proyecto WKND Sites, véase.