Chiamare API interne con certificati privati
Scopri come effettuare chiamate HTTPS da AEM alle API web con certificati privati o autofirmati.
Per impostazione predefinita, quando si tenta di stabilire una connessione HTTPS a un’API web che utilizza un certificato autofirmato, la connessione non riesce e viene mostrato il seguente messaggio di errore:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Questo problema si verifica in genere quando il certificato SSL dell’API non è rilasciato da un’autorità di certificazione (CA) riconosciuta e l’applicazione Java™ non è in grado di convalidare il certificato SSL/TLS.
Scopri come chiamare correttamente le API con certificati privati o autofirmati utilizzando Apache HttpClient e l’Archivio fonti attendibili globale di AEM.
Prototipo di codice di chiamata API con HttpClient
Il codice seguente effettua una connessione HTTPS a un’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
...
Il codice utilizza le classi di libreria HttpClient di Apache HttpComponent e i relativi metodi.
HttpClient e caricare il materiale dall’Archivio fonti attendibili di AEM
Per chiamare un endpoint API con certificato privato o autofirmato, SSLContextBuilder di HttpClient deve essere caricato con l’Archivio fonti attendibili di AEM e utilizzato per facilitare la connessione.
Segui i passaggi seguenti:
-
Accedi a AEM Author come amministratore.
-
Passa a AEM Author > Strumenti > Sicurezza > Archivio fonti attendibili e apri l’Archivio attendibile globale. Se è il primo accesso, imposta una password per l’archivio attendibile globale.
-
Per importare un certificato privato, fai clic sul pulsante Seleziona un file di certificato e seleziona il file di certificato desiderato con estensione
.cer. Per importare, fai clic sul pulsante Invia. -
Aggiorna il codice Java™ come segue. Tieni presente che per utilizzare
@Referenceper ottenereKeyStoreServicedi AEM, il codice di chiamata deve essere un componente o servizio OSGi oppure un modello Sling (in cui è utilizzato@OsgiService).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; } ...- Inserisci nel tuo componente OSGi il servizio OSGi
com.adobe.granite.keystore.KeyStoreServiceintegrato. - Ottieni l’Archivio attendibile globale di AEM utilizzando
KeyStoreServiceeResourceResolver. Questa operazione viene eseguita dal metodogetAEMTrustStore(...). - Crea un oggetto
SSLContextBuilder; consulta i dettagli API di Java™. - Carica l’Archivio attendibile globale di AEM in
SSLContextBuilderutilizzando il metodoloadTrustMaterial(KeyStore truststore,TrustStrategy trustStrategy). - In questo metodo, passa
nullperTrustStrategy, affinché l’esecuzione dell’API risulti riuscita solo per i certificati attendibili di AEM.
- Inserisci nel tuo componente OSGi il servizio OSGi
Evitare modifiche al registro chiavi JVM
Un approccio convenzionale per richiamare in modo efficace le API interne con certificati privati comporta la modifica del registro chiavi JVM. A tal fine, si importano i certificati privati mediante il comando keytool di Java™.
Tuttavia, questo metodo non è allineato alle best practice di sicurezza e AEM offre un’opzione superiore tramite l’utilizzo dell’Archivio attendibile globale e del KeyStoreService.
Pacchetto di soluzioni
Il progetto Node.js di esempio illustrato nel video può essere scaricato da qui.
Il codice servlet di AEM è disponibile nel ramo tutorial/web-api-invocation del progetto WKND Sites, disponibile qui.