首页 > 解决方案 > java中的Http调用不发送客户端证书

问题描述

我正在使用Apache HTTP client(version 4.5.13) inJava 8执行 POST 调用,该调用要求客户端使用我存储在 .PFX 文件中的证书进行身份验证。

这是我正在使用的代码:

public static void performClientRequest() throws Exception {
    //Trust Strategy to accept any server certificate
    TrustStrategy trustStrategy = new TrustStrategy() {
        public boolean isTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            return true;
        }
    };
    
    //Load PFX client certificate
    KeyStore clientStore  = KeyStore.getInstance("PKCS12"); 
    InputStream instream = new FileInputStream("C:\\client.pfx");
    try {
        clientStore.load(instream, null);
    } finally {
        instream.close();
    }

    //Create ssl context with key store and trust strategy 
    SSLContext sslContext = SSLContexts.custom()
            .loadKeyMaterial(clientStore, null)
            .loadTrustMaterial(trustStrategy)
            .build();
    
    //Create ssl socket factory from context
    SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    
    //Create HTTP client
    HttpClient httpClient = HttpClients.custom()
            .setSSLSocketFactory(sslSocketFactory)
            .build();
    
    //Perform call
    URI url = new URI("https://mysite.foo"); 
    HttpPost request = new HttpPost(url);
    
    request.setHeader("Content-Type","application/json"); 
    request.setHeader("Accept", "application/json");
    
    String body = "...";
    StringEntity bodyEntity = new StringEntity(body);
    request.setEntity(bodyEntity);
            
    HttpResponse response = httpClient.execute(request);
    HttpEntity entity = response.getEntity();

    System.out.println("----------------------------------------");
    System.out.println(response.getStatusLine());
    EntityUtils.consume(entity);
}

我过去使用过这段代码,当时它运行良好,但现在我试图重用它,它只是不发送证书,服务器回复:

HTTP/1.1 403 No client certificate supplied

我该如何调试它并发现为什么没有发送证书?

注意C#:我在 in和 using中都实现了一个类似的调用Postman,并且在这两种情况下它都运行良好,因此对服务器的客户端证书身份验证正在运行,它只是在我的 Java 实现中不起作用。

标签: javajava-8apache-httpcomponents

解决方案


所以,我不知道这是错误还是预期行为(如果是,为什么?),但显然 PFX 文件必须受密码保护,然后才能正确发送。我无法使用不受保护的 PFX 文件来完成这项工作,并null像在问题中发布的代码中那样作为密码传递。

所以问题解决了,但我很好奇是否有人可以评论为什么会发生这种情况。


推荐阅读