WebLogic で HTTPS クライアント / カスタムトラスト ( Custom Trust )

WebLogic 自身が HTTPS クライアントになるサンプルコード ( サーブレット ) 書いてみたので、メモしておきます。

サンプルは以下の感じです。WebLogic 側に HttpsURLConnection クラスなる API が用意されているみたいなのでこいつを使ってます。

・HttpsURLConnection (Java API Reference for Oracle WebLogic Server)
https://docs.oracle.com/middleware/1213/wls/WLAPI/weblogic/net/http/HttpsURLConnection.html

■ HttpsClient.java

package https.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import weblogic.net.http.HttpsURLConnection;

@WebServlet("/HttpsClient")
public class HttpsClient extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public HttpsClient() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		URL url = new URL("https://centos62.example.com/test.html");
		HttpsURLConnection connection = new HttpsURLConnection(url);
		connection.connect();
		BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
		String body;
		StringBuffer sb = new StringBuffer();
		while ((body = reader.readLine()) != null) {
			sb.append(body);
		}
		response.getWriter().println(sb.toString());
	}
}


ただ、WebLogicサーバ証明書が信頼できるどうかわからない状況で ( 具体的には WebLogic のトラストのキーストアにサーバ証明書を発行した認証局ルート証明書がインポートされてない状況 )、上記を実行してもお決まりの sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target が発生しちゃいます。

・・・・・
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
	at sun.security.validator.Validator.validate(Validator.java:260)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:107)
	at weblogic.security.SSL.jsseadapter.JaTrustManager.checkServerTrusted(JaTrustManager.java:128)
	at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:827)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1328)
	... 33 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
	... 41 more


なので、トラストのキーストアにルート証明書をインポートしてやる必要があります。管理コンソールの「Custom Identity and Custom Trust」から設定できるみたいです。手順は

* 管理コンソールの [環境] - [サーバ] - [AdminServer(管理サーバー)] をクリック
* [構成] タブ - [キーストア] タブ - [変更] をクリック
* [カスタム・アイデンティティとカスタム信頼] を選択して [保存] をクリック
* [カスタム信頼キーストア] にルート証明書インポートしたキーストアのパスを指定
* [カスタム信頼キーストアのタイプ] は jks と入力
* [カスタム信頼キーストアのパスフレーズ] と [カスタム信頼キーストアのパスフレーズを確認] はキーストアのパスフレーズを入力
* [保存] をクリック

です ( 起動モードとか関係しそうですが「開発者モード」で起動している場合は特に再起動は不要でした )。

※ キーストアは cacert.pem がルート証明書とすると以下のコマンドで作成できる。

keytool -import -alias catest -file cacert.pem -keystore castore


上記の設定実施後、再度、サーブレット実行すると今度は test.html の内容が表示されるはずです。

以上です。

・30 Configuring Keystores
- Configuring Keystores Using the Administration Console
https://docs.oracle.com/middleware/1213/wls/SECMG/identity_trust.htm#SECMG793

[ 環境情報 ]
Windows 7 SP1
WebLogic 12c ( 12.1.3 )
Java SE 7 Update 51

CentOS 6.2
Apache HTTP Server 2.2.15 ( HTTPS 有効 )