HttpClient的”javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”异常
2014-12-21 19:00
465 查看
在开发https应用时,你的测试服务器常常没有一个(有效的)SSL证书。在你的客户端连接测试服务器时,如下的异常会被抛出:”javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”。
我将讨论使用Apache HttpClient时,解决该问题的一种方法(http://hc.apache.org/httpcomponents-client/)。
通常,你会像下面那样来创建HttpClient:
我们将需要告诉client使用一个不同的TrustManager。TrustManager(http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/api/javax/net/ssl/TrustManager.html)是一个检查给定的证书是否有效的类。SSL使用的模式是X.509(http://en.wikipedia.org/wiki/X.509),对于该模式Java有一个特定的TrustManager,称为X509TrustManager。首先我们需要创建这样的TrustManager。
下面我们需要找到一个将TrustManager设置到我们的HttpClient的方法。TrustManager只是被SSL的Socket所使用。Socket通过SocketFactory创建。对于SSL Socket,有一个SSLSocketFactory(http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/api/javax/net/ssl/SSLSocketFactory.html)。当创建新的SSLSocketFactory时,你需要传入SSLContext到它的构造方法中。在SSLContext中,我们将包含我们新创建的TrustManager。
首先我们需要得到一个SSLContext:
TLS是SSL的继承者,但是它们使用相同的SSLContext。
然后我们需要使用我们上面新创建的TrustManager来初始化该上下文:
最后我们创建SSLSocketFactory:
现在我们仍然需要将SSLSocketFactory注册到我们的HttpClient上。这是在SchemeRegistry中完成的:
我们注册了一个新的Scheme,使用协议https,我们新创建的SSLSocketFactory包含了我们的TrustManager,然后我们告诉HttpClienthttps的默认端口是443.
下面的类接收HttpClient作为参数,然后返回一个新的接受任意SSL证书的HttpClient:
我将讨论使用Apache HttpClient时,解决该问题的一种方法(http://hc.apache.org/httpcomponents-client/)。
1. 代码片段
通常,你会像下面那样来创建HttpClient:我们将需要告诉client使用一个不同的TrustManager。TrustManager(http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/api/javax/net/ssl/TrustManager.html)是一个检查给定的证书是否有效的类。SSL使用的模式是X.509(http://en.wikipedia.org/wiki/X.509),对于该模式Java有一个特定的TrustManager,称为X509TrustManager。首先我们需要创建这样的TrustManager。
下面我们需要找到一个将TrustManager设置到我们的HttpClient的方法。TrustManager只是被SSL的Socket所使用。Socket通过SocketFactory创建。对于SSL Socket,有一个SSLSocketFactory(http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/api/javax/net/ssl/SSLSocketFactory.html)。当创建新的SSLSocketFactory时,你需要传入SSLContext到它的构造方法中。在SSLContext中,我们将包含我们新创建的TrustManager。
首先我们需要得到一个SSLContext:
TLS是SSL的继承者,但是它们使用相同的SSLContext。
然后我们需要使用我们上面新创建的TrustManager来初始化该上下文:
最后我们创建SSLSocketFactory:
现在我们仍然需要将SSLSocketFactory注册到我们的HttpClient上。这是在SchemeRegistry中完成的:
我们注册了一个新的Scheme,使用协议https,我们新创建的SSLSocketFactory包含了我们的TrustManager,然后我们告诉HttpClienthttps的默认端口是443.
2. 完整示例代码
下面的类接收HttpClient作为参数,然后返回一个新的接受任意SSL证书的HttpClient:package com.vixuan.vplex; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.ParseException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; public class PostDemo { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub //请求格式https://mgmt-server-ip/vplex/clusters/cluster-name String url="https://172.16.1.5/vplex/clusters/cluster-1"; List<NameValuePair> params=new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("Username","Service")); params.add(new BasicNameValuePair("Password","Mi@Dim77")); params.add(new BasicNameValuePair("args","cluster status")); String result=sendPost(url,params); System.out.println(result); } public static String sendPost(String url,List<NameValuePair> params){ String result=""; HttpClient client1 = new DefaultHttpClient(); HttpClient client =WebClientDevWrapper.wrapClient(client1); HttpPost httppost = new HttpPost(url); try { // Post请求 // 设置参数 httppost.setEntity(new UrlEncodedFormEntity(params,"UTF-8")); // 发送请求 HttpResponse httpresponse = client.execute(httppost); HttpEntity entity = httpresponse.getEntity(); result = EntityUtils.toString(entity); System.out.println(result); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; } <span style="color:#ff0000;"> public static class WebClientDevWrapper { public static HttpClient wrapClient(HttpClient base) { try { SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } public X509Certificate[] getAcceptedIssuers() { // TODO Auto-generated method stub return null; } }; ctx.init(null, new TrustManager[] { tm }, null); SSLSocketFactory ssf = new SSLSocketFactory(ctx); ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); ClientConnectionManager ccm = base.getConnectionManager(); SchemeRegistry sr = ccm.getSchemeRegistry(); //设置要使用的端口,默认是443 sr.register(new Scheme("https", ssf, 443)); return new DefaultHttpClient(ccm, base.getParams()); } catch (Exception ex) { ex.printStackTrace(); return null; } }</span> } }
相关文章推荐
- https应用:避免HttpClient的”javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”异常
- https应用:避免HttpClient的”javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”异常
- 避免HttpClient的”javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”异常
- 避免HttpClient的”javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”异常
- 避免HttpClient的”javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”异常
- 避免HttpClient的”javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”异常
- javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
- HttpClient javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
- javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
- NO.91 SSLPeerUnverifiedException 问题之解决(附HttpClientUtils升级版)
- 用httpclient发送https协议请求以及javax.net.ssl.SSLHandshakeException解决办法
- xUtils3 Https请求报错:javax.net.ssl.SSLPeerUnverifiedException: Hostname ***.****.**not verified,跳过证书检测
- android javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
- Android javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
- 新浪微博:javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
- Cas单点登录配置SSL时遇到的javax.net.ssl.SSLPeerUnverifiedException问题的解决方法
- Exception : javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
- Android QQ授权时 javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
- android javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
- javax.net.ssl.SSLPeerUnverifiedException: No peer certificate【已解决】