使用 Post 请求在 HTTP 客户端中启用 TLS

Posted

技术标签:

【中文标题】使用 Post 请求在 HTTP 客户端中启用 TLS【英文标题】:Enable TLS in HTTP client with Post request 【发布时间】:2016-11-01 02:16:50 【问题描述】:

我想将 TLS 1.2 添加到下面的代码中,尝试通过创建套接字但没有运气。有人可以帮忙吗?创建客户端后可以添加吗?

  private static int executeSOAPRequest(String req, String targetURL)
        throws Exception 
    PostMethod post = new PostMethod(targetURL);
    post.setRequestBody(req);
    post.setRequestHeader("Content-type",
            "text/xml; characterset=ISO-8859-1");
    post.setRequestHeader("SOAPAction", "\"\"");

    // prepare HTTP Client
    HttpClient client = new HttpClient();
    client.getParams().setParameter("SOAPAction", "\"\"");

    // Post the request
    int respCode = client.executeMethod(post);
    System.out.println(post.getResponseBodyAsString());
    // If response is not success
    if (respCode != 200)
        throw new Exception("Executing SOAP request has failed.");
    // Convert the response into NOM XML
    int resp = 0;
    Document doc = nomDocPool.lendDocument();
    try 
        resp = doc.parseString(post.getResponseBodyAsString());
        nomDocPool.returnDocument(doc);
     catch (XMLException e) 
        nomDocPool.returnDocument(doc);
        //logger.error("Exception while generating SAML : "
                //+ e);
        throw e;
    
System.out.println("resp: "+resp);
    return resp;

【问题讨论】:

我想给上面的代码设置TLS 你用的是什么版本的java? Java 8 的 TLS 默认值比 Java 7 好得多。 我使用的是 java 7,现在我无法升级 【参考方案1】:

HttpClient 已经为您处理 TLS。这是记录在案的:

http://hc.apache.org/httpclient-3.x/sslguide.html

HttpClient 通过利用 Java 安全套接字扩展 (JSSE) 为基于安全套接字层 (SSL) 或 IETF 传输层安全 (TLS) 协议的 HTTP 提供全面支持。 JSSE 自 1.4 版起已集成到 Java 2 平台中,可与开箱即用的 HttpClient 一起使用。

您所要做的就是确保您的targetURL 使用https:// 而不是http://,然后HttpClient 为您处理其余的事情。

【讨论】:

我在我的 targetURL 中传递 https。在我的情况下,我有一个肥皂请求和端点(targetURL),所以我们将此请求发送到外部系统,外部系统更改为 TLS v 1.2,所以我收到错误 我尝试与 Salesforce 连接,我收到以下错误 "schemas.xmlsoap.org/soap/envelope" xmlns:sf="urn:fault.enterprise.soap.sforce.com " xmlns:xsi="w3.org/2001/…: TLS 1.0 已在此组织中禁用。使用 https 连接到 Salesforce 时,请使用 TLS 1.1 或更高版本。【参考方案2】:

忘记 HttpClient。使用 javax.net.ssl.HttpsURLConnection

String myResponse = null;
URL url = new URL(targetURL);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();

con.setRequestProperty("Content-Type", "text/xml; characterset=ISO-8859-1");
con.setRequestProperty("SOAPAction", "\"\"");

con.setRequestMethod("POST");       
con.setDoInput(true);
con.setDoOutput(true);      
con.setSSLSocketFactory(My_Lovely_CertificateHelper.getSslSocketFactory());
con.connect();

OutputStream os = con.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "ISO-8859-1");
osw.write(req);
osw.flush();
osw.close();

InputStream is = null;
if (con.getResponseCode() < HttpsURLConnection.HTTP_BAD_REQUEST) 
    is = con.getInputStream();
 else 
    is = con.getErrorStream();

InputStreamReader isr = new InputStreamReader(is, "ISO-8859-1");

int read = -1;
char[] buff = new char[1024];
StringBuilder sb = new StringBuilder();

while ((read = isr.read(buff)) != -1) 
    sb.append(buff, 0, read);

myResponse = sb.toString();
return myResponse;      

getSslSocketFactory()

public static SSLSocketFactory getSslSocketFactory() throws Exception 
        SSLContext sc = SSLContext.getInstance("TLSv1.2");
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        String trustStorePath = getcertPath();  //"user.dir" + "\ohHappyDays.jks";
        String password = "finallyFoundLoveIn2021";
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(new FileInputStream(trustStorePath), password.toCharArray());
        kmf.init(ks, password.toCharArray());
        sc.init(kmf.getKeyManagers(), (TrustManager[]) null, (SecureRandom) null);
        return sc.getSocketFactory();

【讨论】:

以上是关于使用 Post 请求在 HTTP 客户端中启用 TLS的主要内容,如果未能解决你的问题,请参考以下文章

常用压测工具

从Angular2应用程序发送http post请求时如何启用CORS

通过 XML HTTP 请求发布发送密码(启用 HTTPS)

在 Ruby 中发送 HTTP/2 POST 请求

Apache HTTP 客户端,POST 请求。如何正确设置请求参数?

在Ruby中发送HTTP / 2 POST请求