使用带有标头的REST客户端时获取ssl.SSLHandshakeException但与PostMan一起正常工作 [英] Getting ssl.SSLHandshakeException when using REST client with header but works fine with PostMan

查看:244
本文介绍了使用带有标头的REST客户端时获取ssl.SSLHandshakeException但与PostMan一起正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个外部REST资源,其中包含以下详细信息:


  1. 网址: abc.com/orders (域名为 https

  2. 我需要将UserID作为带有密钥user的HTTP标头传递价值是abcd

  3. 这将返回JSON回复

我在下面使用用于此的Java代码:

  try {

客户端客户端= 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){
抛出新的RuntimeException(失败:HTTP错误代码:+ response.getStatus());
}

String output = response.getEntity(String.class);

System.out.println(从服务器输出...... \ n);
System.out.println(输出);

} catch(例外e){

e.printStackTrace();

}

但我得到的是异常,尽管它与 PostMan

  com.sun.jersey.api.client.ClientHandlerException:javax .net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法在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)

我试图搜索一点点,发现我需要从那个U获得证书RL并添加到 jdk / lib / security 文件夹。但我不知道如何继续。



使用openssl我得到低于输出:

  user> openssl s_client -connect abc.com:443 

CONNECTED(00000214)
7832:错误:14077438:SSL例程:SSL23_GET_SERVER_HELLO:tlsv1 alert内部错误:s23_clnt .c:802:
---
没有可用的对等证书
---
没有客户证书CA名称已发送
---
SSL握手已读取7个字节并写入308个字节
---
新增,(无),密码为(无)
不支持安全重新协商
压缩:无
扩展:无
无ALPN协商
SSL-Session:
协议:TLSv1.2
密码:0000
会话ID:
会话ID- ctx:
Master-Key:
Key-Arg:无
PSK身份:无
PSK身份提示:无
SRP用户名:无
开始时间:1531657560
超时:300(秒)
验证返回代码:0(ok)


解决方案

这些是使程序运行的说明。顺便说一句,我在Windows上,使用谷歌浏览器。



你确实需要一个证书。



1)首先,转到网址(无论如何这是一个网站或一个宁静的服务),让我们选择google.com。右键单击页面并单击检查。





2)转到安全标签。





3)一旦你在那里,点击查看证书。



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



4)转到认证路径选项卡。并从层次结构中双击所需的证书。



将弹出一个新窗口:



< a href =https://i.stack.imgur.com/MqBwE.png =nofollow noreferrer>



我在这种情况下选择了根证书称为Google信任服务...,但您可以选择更多特定的,如谷歌互联网管理局G3。我认为它越具体,它提供的安全性就越高(但我不确定)。



5)转到详细信息选项卡并选择您的证书姓名:





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



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



1)查找运行应用程序的JRE,例如我的计算机上只有一个JRE(不包括与JDK捆绑在一起的那个)。它位于:





目标文件商店证书是cacerts:





2)打开cmd作为管理员并执行 cdC:\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 *



注意别名可以是任何东西,不管是什么你调用了你的文件,只要它不与trustst中已有的其他证书的别名冲突矿石。



在我的情况下,我发出这个:





在我的情况下一切正常。



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


I have an external REST resource with below details:

  1. The URL: abc.com/orders (the domain is with https)
  2. I need to pass UserID as an HTTP header with key "user" value is "abcd"
  3. This would return an JSON response

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 .... \n");
            System.out.println(output);

        } catch (Exception e) {

            e.printStackTrace();

        }

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)

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.

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)

解决方案

These are the instructions to make your program work. Btw, I am on windows, using google chrome.

You do need a certificate.

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) Go to the security tab.

3) Once, you're there, click "view certificate".

A window will pop up, with site's certificate's details.

4) Go to the "certification path" tab. And double click on the certificate that you want from the hierarchy.

A new window will pop up:

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) Go to the "Details" tab and choose your certificate's name:

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".

Now you are done exporting the certificate. Next, you want to add it to jvm's truststore.

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:

The target file that stores certificates is cacerts:

2) Open cmd as administrator and do cd "C:\Program Files\Java\jre-10.0.1\lib\security" (path to cacerts in my case).

3) Issue the following command:

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) 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) 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.

这篇关于使用带有标头的REST客户端时获取ssl.SSLHandshakeException但与PostMan一起正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆