Anropa interna API:er med privata certifikat

Lär dig hur du gör HTTPS-anrop från AEM till webb-API:er med privata eller självsignerade certifikat.

Som standard misslyckas anslutningen när du försöker skapa en HTTPS-anslutning till ett webb-API som använder ett självsignerat certifikat. Fel:

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Det här problemet inträffar vanligtvis när API:ts SSL-certifikat inte har utfärdats av en erkänd certifikatutfärdare (CA) och Java™-programmet inte kan validera SSL-/TLS-certifikatet.

Låt oss lära oss hur du kan anropa API:er som har privata eller självsignerade certifikat med hjälp av Apache HttpClient och AEM global TrustStore.

Prototypisk API-anropskod med HttpClient

Följande kod skapar en HTTPS-anslutning till ett webb-API:

...
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
...

Koden använder Apache HttpComponents HttpClient -biblioteksklasser och deras metoder.

HttpClient och läsa in AEM TrustStore-material

Om du vill anropa en API-slutpunkt som har privat eller självsignerat certifikat måste SSLContextBuilder för HttpClient läsas in med AEM TrustStore och användas för att underlätta anslutningen.

Följ stegen nedan:

  1. Logga in på AEM författare som administratör.

  2. Navigera till AEM Författare > Verktyg > Säkerhet > Lita på butik och öppna Global Trust Store. Om du försöker komma åt den första gången anger du ett lösenord för Global Trust Store.

    Global Trust Store

  3. Om du vill importera ett privat certifikat klickar du på knappen Välj certifikatfil och väljer önskad certifikatfil med tillägget .cer. Importera den genom att klicka på knappen Skicka.

  4. Uppdatera Java™-kod enligt nedan. Observera att om du vill använda @Reference för att få AEM KeyStoreService måste anropskoden vara en OSGi-komponent/tjänst, eller en Sling-modell (och @OsgiService används där).

    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;
    }
    
    ...
    
    • Mata in OTB com.adobe.granite.keystore.KeyStoreService OSGi-tjänsten i OSGi-komponenten.
    • Hämta den globala AEM TrustStore med KeyStoreService och ResourceResolver, det gör metoden getAEMTrustStore(...).
    • Skapa ett objekt av SSLContextBuilder, se Java™ API-information.
    • Läs in den globala AEM TrustStore till SSLContextBuilder med metoden loadTrustMaterial(KeyStore truststore,TrustStrategy trustStrategy).
    • Skicka null för metoden TrustStrategy i ovanstående säkerställer att endast AEM betrodda certifikat lyckas under API-körningen.
CAUTION
API-anrop med giltiga CA-utfärdade certifikat misslyckas när de körs med den angivna metoden. Endast API-anrop med AEM betrodda certifikat kan lyckas när den här metoden används.
Använd standardmetoden för att köra API-anrop av giltiga CA-utfärdade certifikat, vilket innebär att endast API:er som är kopplade till privata certifikat ska köras med den tidigare nämnda metoden.

Undvik JVM-nyckelbehållarändringar

Ett vanligt tillvägagångssätt för att effektivt anropa interna API:er med privata certifikat är att ändra JVM-nyckelbehållaren. Detta uppnås genom att importera privata certifikat med kommandot Java™ keytool .

Den här metoden är dock inte anpassad efter bästa säkerhetspraxis och AEM erbjuder ett överlägset alternativ genom att använda Global Trust Store och KeyStoreService.

Lösningspaket

Exempelprojektet Node.js som har nedgraderats i videon kan hämtas från här.

Den AEM serletkoden är tillgänglig i WKND Sites Projects tutorial/web-api-invocation-gren, se.

recommendation-more-help
c92bdb17-1e49-4e76-bcdd-89e4f85f45e6