https 发送get或post请求时忽略证书认证方式

原创地址:http://www.cnblogs.com/shipengzhi/archive/2012/08/22/2650953.html

在开发java时调用别人接口(这个接口还是https开头的)过程中,需要认证你的证书,然而测试服务器常常没有一个(有效的)SSL证书。在你的客户端连接测试服务器时,如下的异常会被抛出:”javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”。

1.解决思路

我们将需要告诉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.


下面上代码:

1.使用的jar包:

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.1.2</version>
</dependency>

2.在已有的util类中写:


/**
 * 避免HttpClient”SSLPeerUnverifiedException: peer not authenticated”异常
 * 不用导入SSL证书
 */
public static class WebClientPassWrapper {

    public static org.apache.http.client.HttpClient wrapClientPass(org.apache.http.client.HttpClient base) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
                public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
            };
            ctx.init(null, new TrustManager[] { tm }, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            SchemeRegistry registry = new SchemeRegistry();
            //https 
            registry.register(new Scheme("https", 443, ssf));
            //http
            registry.register(new Scheme("http",80,PlainSocketFactory.getSocketFactory()));
            ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(registry);
            return new DefaultHttpClient(mgr, base.getParams());
        } catch (Exception ex) {
            System.out.println("WebClientPassWrapper"+"创建忽略用户证书的HttpClient对象失败,尝试创建普通HttpClient对象");
            ex.printStackTrace();
            return new DefaultHttpClient();
        }
    }
}
 
 

3:使用方式:

 
 
/**
 * http请求工具类,get请求
 * @param url
 * @param params
 * @param resonseCharSet
 * @return
 * @throws Exception
 */
public static String httpGet(String url, Map<String, Object> params,String ...resonseCharSet) throws Exception {
    DefaultHttpClient defaultHttpClient = null;
    BufferedReader bufferedReader = null;
    try {
        defaultHttpClient = new DefaultHttpClient();
        if(params!=null){
            StringBuilder stringBuilder=new StringBuilder();
            Iterator<String> iterator=params.keySet().iterator();
            String key;
            while (iterator.hasNext()){
                key=iterator.next();
                Object val=params.get(key);
                if(val instanceof List){
                    List v= (List) val;
                    for (Object o:v){
                        stringBuilder.append(key).append("=").append(o.toString()).append("&");
                    }
                }else{
                    stringBuilder.append(key).append("=").append(val.toString()).append("&");
                }
            }
            stringBuilder.deleteCharAt(stringBuilder.length()-1);
            url=url+"?"+stringBuilder.toString();
            log.info("url:{}",url);
        }
        //调用忽略认证证书
        defaultHttpClient= (DefaultHttpClient) WebClientPassWrapper.wrapClientPass(defaultHttpClient);
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("Content-Type", "application/json;charset=ut-8");
        HttpResponse httpResponse = defaultHttpClient.execute(httpGet);
        if (httpResponse.getStatusLine().getStatusCode() != 200) {
            String errorLog="请求失败,errorCode:"+httpResponse.getStatusLine().getStatusCode();
            log.info(errorLog);
            throw new Exception(url+errorLog);
        }
        //读取返回信息
        String charSet="utf-8";
        if(resonseCharSet!=null && resonseCharSet.length>0)
            charSet=resonseCharSet[0];
        String output;
        bufferedReader=new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(),charSet));

        StringBuilder dataBuilder=new StringBuilder();
        while ((output=bufferedReader.readLine())!=null){
            dataBuilder.append(output);
        }
        return dataBuilder.toString();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
        throw e;
    }catch (IOException e){
        e.printStackTrace();
        throw e;
    }finally {
        if(defaultHttpClient!=null)
            defaultHttpClient.getConnectionManager().shutdown();
        if(bufferedReader!=null)
            bufferedReader.close();
    }
}


到这里就结束了,也是借鉴别人的思路,可以动手试试

猜你喜欢

转载自blog.csdn.net/qq_32403351/article/details/79917733