Apache HttpClientとオレオレ認証
広く使われている HTTPクライアントである Apache HttpComponentsを使って SSL通信のプログラムを作るとき、きちんとした証明書を利用せず簡易的に用意した証明書を利用したサーバーを使って開発を行います。 その際、証明書エラーで行き詰まらないように全ての証明書を受け付けるように設定してしまいます。
HttpClient 4.2 の場合の記述
try { SSLContext sslContext = SSLContext.getInstance("SSL"); // 全ての証明書を受け付ける TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }; sslContext.init(null, new TrustManager[] { tm }, null); // スキーマの設定 SSLSocketFactory factory = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); Scheme httpScheme = new Scheme("http", PORT_HTTP, PlainSocketFactory.getSocketFactory()); Scheme httpsScheme = new Scheme("https", PORT_HTTPS, factory); SchemeRegistry registry = new SchemeRegistry(); registry.register(httpScheme); registry.register(httpsScheme); // 接続 ClientConnectionManager cm = BasicClientConnectionManager(registry); // パラメータ設定 HttpParams params = new basicHttpParams(); HttpConnectionParams.setSocketBufferSize(params, 4096); // ソケットバッファサイズ //HttpConnectionParams.setSoTimeOut(params, 10000); // 通信タイムアウト HttpConnectionParams.setConnectionTimeOut(params, 1000); // コネクションタイムアウト HttpProtocolParams.setContentChaset(params, 'UTF-8'); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); DefaultHttpClient httpClient = new DefaultHttpClient(cm, params); ... } catch (KeyManagementException | NoSuchAlgorithmException e) { logger.error("エラー処理"); }
HttpClient 4.3 で大きくインターフェースが変わったみたいだけど・・・見直した頃には 4.4 になっていたので無視!
HttpClient 4.4 の場合の記述
どのパッケージのものをインポートするかきちんと選ばないと動かないので import文もあげておきます。
import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; ... import javax.net.ssl.SSLContext; ... import org.apache.http.Header; import org.apache.http.client.config.RequestConfig; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.impl.impl.CloseableHttpClient; import org.apache.http.impl.impl.HttpClientBuilder; import org.apache.http.message.BasicHeader; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.TrustStrategy; ... // タイムアウト設定 RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(1000) // コネクションタイムアウト //.setSocketTimeout(10000) // 通信タイムアウト .build(); // ヘッダー情報 List<Header> header = new ArrayListt<Header>(); header.add(new BasicHeader("Accept-Charaset", "UTF-8")); header.add(new BasicHeader("Accept-Language", "ja, en;")); header.add(new BasicHeader("User-Agent", "My Http Client 1.0")); // すべての認証を受け付ける try { SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy(){ public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } ).build(); CloseableHttpClient httpClient = HttpClientBuilder.create() .setSslcontext(sslContext) .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) .setDefaultRequestConfig(requestConfig) .setDefaultHeaders(header) .build(); ... } catch (KeyManagementException | NoSuchAlgorithmException | KetStoreException e) { logger.error("エラー処理"); }
HttpClient 4.5 でも変わったらしい。。。もういいや。。。