将REST客户端与标头一起使用时获取ssl.SSLHandshakeException,但与PostMan一起使用时效果很好

时间:2018-07-15 11:53:55

标签: java rest jersey rest-client

我有一个具有以下详细信息的外部REST资源:

  1. URL:abc.com/orders(域为https
  2. 我需要将UserID作为HTTP头传递,其键“ user”值为“ abcd”
  3. 这将返回JSON响应

我正在为此使用以下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)

2 个答案:

答案 0 :(得分:3)

男人!不需要以上任何内容!!! 只需在Rest Api代码之前传递RestAssured.useRelaxedHTTPSValidation();。 完成!`

答案 1 :(得分:2)

这些是使程序正常工作的说明。顺便说一句,我在Windows上,使用Google Chrome。

您确实需要证书。

1)首先,转到url(无论是网站还是宁静的服务都没关系),让我们选择google.com。右键单击页面,然后单击“检查”。

enter image description here

2)转到安全标签。

enter image description here

3)一旦到达,请单击“查看证书”。 enter image description here

将弹出一个窗口,其中包含站点证书的详细信息。

4)转到“认证路径”标签。然后从层次结构中双击所需的证书。 enter image description here

将弹出一个新窗口:

enter image description here

在这种情况下,我选择了根证书,称为“ Google信任服务...”,但是您可以选择更具体的证书,例如“ Google Internet Authority G3”。我认为它越具体,它提供的安全性就越高(但我不确定)。

5)转到“详细信息”标签,然后选择您的证书名称:

enter image description here

6)单击“复制到文件”,然后为其选择名称以及保存位置。我在桌面上保存了我的名字,并将其命名为“ test.cer”。

现在,您已完成导出证书。接下来,您要将其添加到jvm的信任库中。

1)查找您的应用程序在哪个JRE上运行,例如,我的计算机上只有一个JRE(与JDK捆绑在一起的JRE除外)。它位于这里:

enter image description here

存储证书的目标文件是cacerts:

enter image description here

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*

请注意,别名可以是任何内容,无论您叫什么文件,只要它不与信任库中已有的其他证书的别名冲突即可。

就我而言,我发出此消息:

enter image description here

4)您现在可以发出以下命令:keytool -list -keystore cacerts -alias *alias*以确保已添加证书。发出此命令时,它将要求您输入密码。在第三步中,我给您的命令具有以下选项:-storepass changeit,因此您的密码将为changeit

enter image description here

就我而言,一切正常。

5)现在您可以重新启动应用程序,它应该可以正常工作。有人建议重新启动计算机,但是我不知道这是否有必要。