プライベート証明書または自己署名証明書を使用した、AEM から web API への HTTPS 呼び出し方法を説明します。
デフォルトでは、自己署名証明書を使用する web API に HTTPS 接続を確立しようとすると、次のエラーで接続が失敗します。
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
この問題は、通常、API の SSL 証明書が認定された認証局(CA)によって発行されておらず、Java™ アプリケーションが SSL/TLS 証明書を検証できない場合に発生します。
Apache HttpClient と AEM のグローバル TrustStore を使用して、プライベート証明書または自己署名証明書を使用する API を正常に呼び出す方法を学びましょう。
次のコードでは、web API への HTTPS 接続を行います。
...
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
...
このコードでは、Apache HttpComponent の HttpClient ライブラリクラスとそのメソッドを使用します。
プライベート証明書または自己署名証明書を使用する API エンドポイントを呼び出すには、HttpClient の SSLContextBuilder
を AEM の TrustStore で読み込み、接続を簡単にするために使用する必要があります。
次の手順に従います。
AEM オーサーに管理者としてログインします。
AEM オーサー/ツール/セキュリティ/トラストストアに移動し、グローバルトラストストアを開きます。初めてにアクセスする場合は、グローバルトラストストアのパスワードを設定します。
プライベート証明書を読み込むには、「証明書ファイルを選択」ボタンをクリックし、.cer
拡張子が付いた目的の証明書ファイルを選択します。「送信」ボタンをクリックして読み込みます。
Java™コードを以下のように更新します。@Reference
を使用して AEM の KeyStoreService
を取得するには、呼び出しコードを OSGi コンポーネント/サービスや、Sling モデルにする必要があります(そこで @OsgiService
を使用します)。
...
// 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;
}
...
com.adobe.granite.keystore.KeyStoreService
OSGi サービスを OSGi コンポーネントに挿入します。KeyStoreService
と ResourceResolver
を使用してグローバル AEM TrustStore を取得します。これは getAEMTrustStore(...)
メソッドで行います。SSLContextBuilder
のオブジェクトを作成します。Java™ API の詳細を参照してください。loadTrustMaterial(KeyStore truststore,TrustStrategy trustStrategy)
メソッドを使用して、グローバル AEM TrustStore を SSLContextBuilder
に読み込みます。TrustStrategy
に null
を渡すと、API の実行中に AEM の信頼済み証明書のみが成功することが保証されます。前述の方法を使用して実行すると、CA 発行の有効な証明書を使用した API 呼び出しは失敗します。このメソッドに従う場合、AEM の信頼済み証明書を使用した API 呼び出しのみが成功します。
有効な CA 発行の証明書の API 呼び出しを実行するには、標準的な方法を使用します。つまり、プライベート証明書に関連付けられた API のみを、前述のメソッドを使用して実行する必要があります。
プライベート証明書を使用して内部 API を効果的に呼び出す従来の方法には、JVM キーストアの変更が含まれます。これは、Java™ keytool コマンドを使用してプライベート証明書を読み込むことで実現します。
ただし、この方法はセキュリティのベストプラクティスと一致していないので、AEM ではグローバルトラストストアと KeyStoreService を利用することで優れたオプションを提供します。
ビデオでデモされているサンプル Node.js プロジェクトは、こちらからダウンロードできます。
AEM サーブレットコードは、WKND Sites プロジェクトの tutorial/web-api-invocation
ブランチで入手できます。こちらを参照してください。