SpringBoot SSL/TLS接続時の証明書スキップ設定
自己証明書(オレオレ証明書)を生成してサーバー側に設定し、HTTPS接続する方法は下記で説明したとおり
SpringBoot SSL/TLS接続設定
Javaでは証明書とホストの検証を行っている為、クライアント側にも証明書の格納が必要となる
しかも自己証明書ではエラーとなってしまう
開発環境で正式に証明書を発行するというのはあまり現実的ではないので、今回はその証明書をスキップする方法を解説する
【開発の手順】
①Map型のレスポンスを返すAPIを作成(HTTPSで接続)
②リクエスト用のプロジェクトを作成し、証明書スキップ設定を記述
③②のプロジェクトを完成させる
④①のAPIのJarを作成する
⑤仮想サーバーを立ち上げ、デプロイ
⑥動作確認
★証明書スキップのメイン部分は手順②
その他は参考程度に見るだけも良い
以下、作成手順
①Map型のレスポンスを返すAPIを作成(HTTPSで接続)
※作成方法は下記を参考にkeytoolコマンドで秘密鍵・公開鍵の生成、keystoreフォルダに格納する
また、application.propertiesにHTTPS有効化の設定を記述する
SpringBoot SSL/TLS接続設定
今回はシンプルにMap型インスタンスを返すAPIを作成
・ResponseController.java
パス:[メインパッケージ]/api/ResponseController.java
package com.example.api;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ResponseController {
@GetMapping
Map<Integer, String> responseMap() {
Map<Integer, String> map = new HashMap<>();
map.put(1, "ryotsu");
return map;
}
}
②リクエスト用のプロジェクトを作成し、証明書スキップ設定を記述
HTTPクライアントのライブラリ使用できるようにする為に、「build.gradle」の「dependencies」ブロックに下記を追記
implementation 'org.apache.httpcomponents:httpclient:4.5.12'
configパケージを作成し、その直下に証明書スキップ設定クラスとなる「RestTemplateConfig.java」を作成する
・RestTemplateConfig.java
パス:[メインパッケージ]/config/RestTemplateConfig.java
package com.example.config;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() throws Exception {
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(new TrustSelfSignedStrategy()).build(); //TrustSelfSignedStrategyで自己署名証明書を許可する設定
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) //ホスト名の検証しない設定
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
RestTemplate restTemplate = new RestTemplate(requestFactory);
((HttpComponentsClientHttpRequestFactory) restTemplate
.getRequestFactory()).setHttpClient(httpClient); //RestTemplateで使うhttpClientを自己署名証明書対応されたClientに差し替え
return restTemplate;
}
}
【ポイント】
・@Configuration付与
Configurationアノテーションで設定クラスに指定する
これによりプロジェクトが起動した際にこのクラスが読み込まれるようになる
・@Bean付与
Beanアノテーションで「restTemplate」というBeanをDIコンテナに格納する
※メソッド名がBean名になる
・その他はソース内のコメントのとおり
③②のプロジェクトを完成させる
※①のAPIにリクエストを送り、レスポンスを受け取る
・RequestController.java
パス:[メインパッケージ]/rest/RequestController.java
package com.example.rest;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class RequestController {
//開発の手順②で作成したBean(restTemplate)のインスタンスを取得
@Autowired
RestTemplate restTemplate;
@GetMapping
Map<?, ?> index() {
//開発の手順①で作成したAPIのURL
String url = "https://192.168.33.10:8443";
@SuppressWarnings("rawtypes")
ResponseEntity<Map> response = null;
try {
//APIにリクエストをGET送信
response = restTemplate.getForEntity(url, Map.class);
//リクエストがエラーの場合
if (response.getStatusCodeValue() != 200) {
HttpStatus httpStatus = response.getStatusCode();
//エラー理由を取得
String errReason = httpStatus.getReasonPhrase();
//HTTPステータスコードを出力
System.out.println(response.getStatusCodeValue());
//エラー理由を出力
System.out.println(errReason);
}
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println(e.getCause());
}
//レスポンスが無い場合は画面に{"error", "no data"}と表示
if (response == null) {
Map<String, String> map = new HashMap<>();
map.put("error", "no data");
return map;
}
//正常にレスポンスが返ってきた場合は{"1":"ryotsu"}が表示される
//※開発の手順①で作成したAPIのレスポンス結果
return response.getBody();
}
}
④①のAPIのJarを作成する
下記を参考にJarを作成
Gradle Jarの作成・実行
⑤仮想サーバーを立ち上げ、デプロイ
仮想サーバーを設定していない場合は下記を参考にすると良い
但し時間がかかるので余裕がある時に実施をおすすめする
ローカル開発環境構築(Windows)
※【⑩「Tera Term」で下記コマンドを実行して必要なアプリケーションをインストール】以降の設定は不要
更にJavaの設定が必要なので下記を参考に設定する
CentOS OpneJDK11のインストール方法
④で作成したJarをWinSCPなどの転送ツールでデプロイする
下記コマンドでJarを起動
java -jar [Jar名]
⑥動作確認
③で作成したリクエスト用のプロジェクトを起動して下記のように表示されることを確認