使用带有标头的 REST 客户端时获取 ssl.SSLHandshakeException 但与 PostMan 一起工作正常
我有一个包含以下详细信息的外部 REST 资源:
I have an external REST resource with below details:
- 网址:
abc.com/orders
(域名为https
) - 我需要将 UserID 作为 HTTP 标头传递,其中键user"值为abcd"
- 这将返回 JSON 响应
我为此使用下面的 Java 代码:
I am using below Java code for this:
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 ....
");
System.out.println(output);
} catch (Exception e) {
e.printStackTrace();
}
但我遇到了异常,尽管它可以与 PostMan
But I am getting below exception although it works fine with 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
文件夹的地方.但我不知道如何继续.
I tried to search a bit on it and found somewhere that I need to get certificate from that URL and add to jdk/lib/security
folder. But I don't know how to proceed.
使用 openssl 我得到以下输出:
With openssl I get below output:
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)
推荐答案
这些是使您的程序工作的说明.顺便说一句,我在 Windows 上,使用谷歌浏览器.
These are the instructions to make your program work. Btw, I am on windows, using google chrome.
您确实需要证书.
1)首先,进入url(不管是网站还是restful服务),我们选择google.com.右键点击页面,点击检查".
1) First, go to the url (doesn't matter if it's a website or a restful service), let's pick google.com. Right click on the page and click "inspect".
2) 转到安全选项卡.
2) Go to the security tab.
3) 到达那里后,单击查看证书".
3) Once, you're there, click "view certificate".
将弹出一个窗口,其中包含站点证书的详细信息.
A window will pop up, with site's certificate's details.
4) 转到认证路径"选项卡.并从层次结构中双击所需的证书.
4) Go to the "certification path" tab. And double click on the certificate that you want from the hierarchy.
会弹出一个新窗口:
我在本例中选择了名为Google 信任服务..."的根证书,但您可以选择更具体的证书,例如Google Internet Authority G3".我认为它越具体,它提供的安全性就越高(但我不确定).
I chose the root certificate in this case called "Google trust services...", but you can choose a more specific one, like "Google Internet Authority G3". I think the more specific it is, the more security it provides (but I'm not sure).
5) 转到详细信息"选项卡并选择您的证书名称:
5) Go to the "Details" tab and choose your certificate's name:
6) 单击复制到文件",然后选择它的名称以及要保存它的位置.我将我的保存在桌面上并将其命名为test.cer".
6) Click "Copy To File", then choose the name for it and where you want to save it. I saved mine on desktop and named it "test.cer".
现在您已完成证书的导出.接下来,您要将其添加到 jvm 的信任库中.
Now you are done exporting the certificate. Next, you want to add it to jvm's truststore.
1) 查看您的应用程序在哪个 JRE 上运行,例如我的计算机上只有一个 JRE(不包括与 JDK 捆绑的那个).它位于此处:
1) Look up which JRE your application is running on, for example I have only one JRE on my computer (excluding the one bundled with the JDK). It's located here:
存储证书的目标文件是cacerts:
The target file that stores certificates is cacerts:
2) 以管理员身份打开 cmd 并执行 cd "C:Program FilesJavajre-10.0.1libsecurity"
(在我的例子中是 cacerts 的路径).
2) Open cmd as administrator and do cd "C:Program FilesJavajre-10.0.1libsecurity"
(path to cacerts in my case).
3) 发出以下命令:
keytool -import -storepass changeit -noprompt -alias *alias* -keystore cacerts -trustcacerts -file *path_to_certificate*
请注意,别名可以是任何东西,无论您如何称呼您的文件,只要它不与信任库中已有的其他证书的别名冲突.
Note that alias can be anything, regardless of what you called your file, as long as it doesn't clash with aliases of other certificates already in the truststore.
就我而言,我发出这个:
In my case I issue this:
4) 您现在可以发出以下命令:keytool -list -keystore cacerts -alias *alias*
以确保您的证书已添加.当您发出此命令时,它会询问您的密码.第三步,我给你的命令有这个选项:-storepass changeit
,所以你的密码是changeit
.
4) You can now issue this command: keytool -list -keystore cacerts -alias *alias*
to make sure your certificate was added. When you issue this command, it will ask you for your password. In step three, the command I gave your had this option: -storepass changeit
, so your password will be changeit
.
就我而言,一切都很好.
In my case everything is okay.
5) 现在您可以重新启动您的应用程序,它应该可以工作了.有人建议重新启动计算机,但我不知道是否有必要.
5) Now you can restart your application and it should work. Some people recommend restarting your computer, but I don't know if that's necessary.
相关文章