Aufrufen interner APIs, die über private Zertifikate verfügen
Erfahren Sie, wie Sie HTTPS-Aufrufe von AEM zu Web-APIs durchführen, die private oder selbstsignierte Zertifikate verwenden.
Wenn Sie versuchen, eine HTTPS-Verbindung zu einer Web-API herzustellen, die ein selbstsigniertes Zertifikat verwendet, schlägt die Verbindung standardmäßig mit dieser Fehlermeldung fehl:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Dieses Problem tritt in der Regel auf, wenn das SSL-Zertifikat der API nicht von einer anerkannten Zertifizierungsstelle ausgestellt wird und die Java™-Anwendung das SSL/TLS-Zertifikat nicht überprüfen kann.
Im Folgenden erfahren Sie, wie Sie APIs mit privaten oder selbstsignierten Zertifikaten mithilfe von Apache HttpClient und dem globalen TrustStore von AEM erfolgreich aufrufen können.
Prototypischer API-Aufruf-Code unter Verwendung von HttpClient
Der folgende Code stellt eine HTTPS-Verbindung zu einer Web-API her:
...
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
...
Der Code verwendet die HttpClient-Bibliotheksklassen von Apache HttpComponent und deren Methoden.
HttpClient und Laden des Materials aus dem AEM TrustStore
Um einen API-Endpunkt aufzurufen, der über ein privates oder selbstsigniertes Zertifikat verfügt, muss der SSLContextBuilder
des HttpClients mit dem TrustStore von AEM geladen und verwendet werden, um die Verbindung zu erleichtern.
Führen Sie die folgenden Schritte aus:
-
Melden Sie sich bei AEM Author als Admin an.
-
Navigieren Sie zu AEM Author > Tools > Sicherheit > Trust Store und öffnen Sie den Global Trust Store. Legen Sie beim erstmaligen Zugriff ein Kennwort für den Global Trust Store fest.
-
Um ein privates Zertifikat zu importieren, klicken Sie auf Zertifikatdatei auswählen und wählen Sie die gewünschte Zertifikatdatei mit einer
.cer
-Erweiterung aus. Klicken Sie auf Senden, um sie zu importieren. -
Aktualisieren Sie den Java™-Code wie unten beschrieben. Beachten Sie Folgendes: um den AEM
KeyStoreService
mit@Reference
aufrufen zu können, muss der Aufruf-Code eine OSGi-Komponente/Dienst oder ein Sling-Modell sein (und dort@OsgiService
verwendet werden).code language-java ... // 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; } ...
- Fügen Sie den vorkonfigurierten OSGi-Dienst
com.adobe.granite.keystore.KeyStoreService
in Ihre OSGi-Komponente ein. - Rufen Sie den globalen AEM TrustStore mit
KeyStoreService
undResourceResolver
ab. Dies erfolgt mit der MethodegetAEMTrustStore(...)
. - Erstellen Sie ein Objekt von
SSLContextBuilder
, siehe Java™ API-Details. - Laden Sie den globalen AEM TrustStore mit der
loadTrustMaterial(KeyStore truststore,TrustStrategy trustStrategy)
-Methode inSSLContextBuilder
. - Übergeben Sie in der oben genannten Methode
null
fürTrustStrategy
, um sicherzustellen, dass nur vertrauenswürdige AEM-Zertifikate während der API-Ausführung erfolgreich sind.
- Fügen Sie den vorkonfigurierten OSGi-Dienst
Vermeiden von JVM-Keystore-Änderungen
Ein herkömmlicher Ansatz zum effektiven Aufruf interner APIs mit privaten Zertifikaten beinhaltet ein Ändern des JVM-Keystore. Hierzu werden die privaten Zertifikate mithilfe des Java™-Befehls keytool importiert.
Da diese Methode jedoch nicht den Best Practices zur Sicherheit entspricht, bietet AEM eine bessere Option durch die Verwendung des Global Trust Store und des KeyStoreService.
Lösungspaket
Das im Video vorgestellte Node.js-Beispielprojekt kann von hier heruntergeladen werden.
Der AEM-Servlet-Code ist in der Verzweigung tutorial/web-api-invocation
des WKND Sites-Projekts verfügbar, siehe.