mTLS-autentisering (Mutual Transport Layer Security) från AEM

Lär dig hur du gör HTTPS-anrop från AEM till webb-API:er som kräver mTLS-autentisering.

mTLS- eller tvåvägs TLS-autentisering förbättrar TLS-protokollets säkerhet genom att kräva att både klienten och servern autentiserar varandra. Autentiseringen görs med digitala certifikat. Det används ofta i scenarier där stark säkerhet och identitetsverifiering är avgörande.

Som standard misslyckas anslutningen när du försöker göra en HTTPS-anslutning till ett webb-API som kräver mTLS-autentisering. Följande fel uppstår:

javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_required

Det här problemet inträffar när klienten inte har något certifikat som kan autentiseras.

Låt oss lära oss hur du kan anropa API:er som kräver mTLS-autentisering med Apache HttpClient och AEM KeyStore och TrustStore.

HttpClient och läsa in AEM KeyStore-material

På en hög nivå krävs följande steg för att anropa ett mTLS-skyddat API från AEM.

Generering av AEM

Begär AEM certifikat genom att samarbeta med din organisations säkerhetsteam. Säkerhetsteamet tillhandahåller eller frågar om certifikatrelaterade detaljer som nyckel, CSR (Certificate Signing Request) och använder CSR för att utfärda certifikatet.

Generera certifikatrelaterade detaljer som nyckel, CSR (Certificate Signing Request) för demonstrationssyften. I exemplet nedan används en självsignerad certifikatutfärdare för att utfärda certifikatet.

  • Generera först det interna certifikatutfärdarcertifikatet (CA).

    code language-shell
    # Create an internal Certification Authority (CA) certificate
    openssl req -new -x509 -days 9999 -keyout internal-ca-key.pem -out internal-ca-cert.pem
    
  • Generera AEM.

    code language-shell
    # Generate Key
    openssl genrsa -out client-key.pem
    
    # Generate CSR
    openssl req -new -key client-key.pem -out client-csr.pem
    
    # Generate certificate and sign with internal Certification Authority (CA)
    openssl x509 -req -days 9999 -in client-csr.pem -CA internal-ca-cert.pem -CAkey internal-ca-key.pem -CAcreateserial -out client-cert.pem
    
    # Verify certificate
    openssl verify -CAfile internal-ca-cert.pem client-cert.pem
    
  • Konvertera den AEM privata nyckeln till DER-format, AEM KeyStore kräver den privata nyckeln i DER-format.

    code language-shell
    openssl pkcs8 -topk8 -inform PEM -outform DER -in client-key.pem -out client-key.der -nocrypt
    
TIP
De självsignerade CA-certifikaten används endast i utvecklingssyfte. För produktion använder du en betrodd certifikatutfärdare (CA) för att utfärda certifikatet.

Certifikatutbyte

Om du använder en självsignerad certifikatutfärdare för AEM, som ovan, skickar du certifikatet eller det interna certifikatutfärdarcertifikatet till API-providern.

Om API-providern använder ett självsignerat certifikatutfärdarcertifikat tar du dessutom emot certifikatet eller det interna certifikatutfärdarcertifikatet från API-providern.

Certifikatimport

Så här importerar du AEM certifikat:

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

  2. Navigera till AEM Författare > Verktyg > Dokumentskydd > Användare > Skapa eller välj en befintlig användare.

    Skapa eller välj en befintlig användare

    För demoändamål skapas en ny användare med namnet mtl-demo-user.

  3. Klicka på användarnamnet för att öppna användaregenskaperna.

  4. Klicka på fliken Nyckelbehållare och sedan på knappen Skapa nyckelbehållare . Ange sedan ett lösenord för användarens nyckelbehållare i dialogrutan Ange lösenord för KeyStore-åtkomst och klicka på Spara.

    Skapa nyckelbehållare

  5. Följ stegen nedan på den nya skärmen under avsnittet LÄGG TILL PRIVAT KEY FRÅN DER FILE:

    1. Ange alias

    2. Importera den AEM privata nyckeln i DER-format som genereras ovan.

    3. Importera filerna för certifikatkedjan som genererats ovan.

    4. Klicka på Skicka

      Importera AEM privat nyckel

  6. Kontrollera att certifikatet har importerats.

    AEM Privat nyckel och certifikat har importerats

Om API-providern använder ett självsignerat CA-certifikat importerar du det mottagna certifikatet till AEM TrustStore, följer du stegen från här.

Om AEM använder ett självsignerat CA-certifikat ber du API-providern att importera det.

Prototypisk mTLS API-anropskod med HttpClient

Uppdatera Java™-kod enligt nedan. Om du vill använda @Reference-anteckningen för att hämta AEM KeyStoreService-tjänsten måste den anropande koden vara en OSGi-komponent eller en Sling-modell (och @OsgiService används där).

...

// Get AEM's KeyStoreService reference
@Reference
private com.adobe.granite.keystore.KeyStoreService keyStoreService;

...

// Get AEM KeyStore using KeyStoreService
KeyStore aemKeyStore = getAEMKeyStore(keyStoreService, resourceResolver);

if (aemKeyStore != null) {

    // Create SSL Context
    SSLContextBuilder sslbuilder = new SSLContextBuilder();

    // Load AEM KeyStore material into above SSL Context with keystore password
    // Ideally password should be encrypted and stored in OSGi config
    sslbuilder.loadKeyMaterial(aemKeyStore, "admin".toCharArray());

    // If API provider cert is self-signed, load AEM TrustStore material into above SSL Context
    // Get AEM TrustStore
    KeyStore aemTrustStore = getAEMTrustStore(keyStoreService, resourceResolver);
    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(MTLS_API_ENDPOINT));

    // Code that reads response code and body from the 'closeableHttpResponse' object
    ...
}

/**
 * Returns the AEM KeyStore of a user. In this example we are using the
 * 'mtl-demo-user' user.
 *
 * @param keyStoreService
 * @param resourceResolver
 * @return AEM KeyStore
 */
private KeyStore getAEMKeyStore(KeyStoreService keyStoreService, ResourceResolver resourceResolver) {

    // get AEM KeyStore of 'mtl-demo-user' user, you can create a user or use an existing one.
    // Then create keystore and upload key, certificate files.
    KeyStore aemKeyStore = keyStoreService.getKeyStore(resourceResolver, "mtl-demo-user");

    return aemKeyStore;
}

/**
 *
 * 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 användarens AEM KeyStore med KeyStoreService och ResourceResolver, det gör metoden getAEMKeyStore(...).
  • Om API-providern använder ett självsignerat CA-certifikat hämtar du det globala AEM TrustStore, gör metoden getAEMTrustStore(...) det.
  • Skapa ett objekt av SSLContextBuilder, se Java™ API-information.
  • Läs in användarens AEM KeyStore till SSLContextBuilder med metoden loadKeyMaterial(final KeyStore keystore,final char[] keyPassword).
  • Nyckellösenordet är det lösenord som angavs när nyckelbehållaren skapades. Det bör lagras i OSGi-konfigurationen, se Hemliga konfigurationsvärden.

Undvik JVM-nyckelbehållarändringar

Ett vanligt tillvägagångssätt för att effektivt anropa mTLS API:er med privata certifikat är att ändra JVM Keystore. 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 användarspecifika KeyStores och Global TrustStore 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