以下の詳細を持つ外部RESTリソースがあります:
abc.com/orders
(ドメインはhttps
です)私は以下のJavaコードを使用しています:
try {
Client client = Client.create();
WebResource webResource = client.resource("abc.com/orders");
ClientResponse response = webResource.header("user", "abcd").accept("application/json")
.get(ClientResponse.class);
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}
String output = response.getEntity(String.class);
System.out.println("Output from Server .... \n");
System.out.println(output);
} catch (Exception e) {
e.printStackTrace();
}
しかし、PostMan
で正常に動作しますが、例外を下回っています。
com.Sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLHandshakeException: Sun.security.validator.ValidatorException: PKIX path building failed: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.Sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.Java:155)
at com.Sun.jersey.api.client.Client.handle(Client.Java:652)
at com.Sun.jersey.api.client.WebResource.handle(WebResource.Java:682)
at com.Sun.jersey.api.client.WebResource.access$200(WebResource.Java:74)
at com.Sun.jersey.api.client.WebResource$Builder.get(WebResource.Java:509)
それを少し検索してみたところ、そのURLから証明書を取得し、jdk/lib/security
フォルダーに追加する必要があることがわかりました。しかし、私はどのように進めるかわかりません。
Opensslを使用すると、以下の出力が得られます。
user>openssl s_client -connect abc.com:443
CONNECTED(00000214)
7832:error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error:s23_clnt.c:802:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 308 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1531657560
Timeout : 300 (sec)
Verify return code: 0 (ok)
これらは、プログラムを機能させるための手順です。ところで、私はグーグルクロームを使用して、ウィンドウズにいます。
証明書は必要です。
1)まず、URLに移動し(WebサイトであるかRESTfulサービスであるかは関係ありません)、google.comを選択しましょう。ページを右クリックして、「検査」をクリックします。
2)[セキュリティ]タブに移動します。
サイトの証明書の詳細を示すウィンドウがポップアップ表示されます。
4)「認証パス」タブに移動します。そして、階層から必要な証明書をダブルクリックします。
新しいウィンドウがポップアップ表示されます。
この場合、「Googleトラストサービス...」というルート証明書を選択しましたが、「Google InternetAuthorityG3」などのより具体的な証明書を選択することもできます。具体的であればあるほど、セキュリティが強化されると思います(ただし、よくわかりません)。
5)[詳細]タブに移動し、証明書の名前を選択します。
6)[ファイルにコピー]をクリックし、名前と保存場所を選択します。デスクトップに保存して「test.cer」という名前を付けました。
これで、証明書のエクスポートが完了しました。次に、それをjvmのトラストストアに追加します。
1)アプリケーションが実行されているJREを検索します。たとえば、コンピューターにJREが1つしかない(JDKにバンドルされているJREを除く)。それはここにあります:
証明書を格納するターゲットファイルはcacertsです。
2)管理者としてcmdを開き、cd "C:\Program Files\Java\jre-10.0.1\lib\security"
(私の場合はcacertsへのパス)を実行します。
3)次のコマンドを発行します。
keytool -import -storepass changeit -noprompt -alias *alias* -keystore cacerts -trustcacerts -file *path_to_certificate*
エイリアスは、ファイルの名前に関係なく、トラストストアにすでに存在する他の証明書のエイリアスと衝突しない限り、何でもかまいません。
私の場合、私はこれを発行します:
4)これで、次のコマンドを発行できます:keytool -list -keystore cacerts -alias *alias*
証明書が追加されたことを確認するには、このコマンドを発行すると、パスワードの入力を求められます。ステップ3で、私があなたに与えたコマンドには次のオプションがありました:-storepass changeit
、それであなたのパスワードはchangeit
になります。
私の場合、すべてが大丈夫です。
5)これで、アプリケーションを再起動でき、動作するはずです。コンピュータを再起動することを勧める人もいますが、それが必要かどうかはわかりません。
おとこ!上記のどれも必要ありません!!! RestApiコードの前にRestAssured.useRelaxedHTTPSValidation();
を渡すだけです。完了! `