简体   繁体   English

java中的Http调用不发送客户端证书

[英]Http call in java not sending client certificate

I'm using the Apache HTTP client (version 4.5.13 ) in Java 8 to perform a POST call that requires the client to authenticate using a certificate certificate, that I have stored in a .PFX file.我在Java 8使用Apache HTTP client (版本4.5.13 )来执行 POST 调用,该调用要求客户端使用存储在 .PFX 文件中的证书证书进行身份验证。

This is the code I'm using:这是我正在使用的代码:

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);
}

I've used this code in in the past and it worked perfectly back then, but now I'm trying to reuse it and it just doesn't send the certificate, the server replies with:我过去使用过这段代码,当时它运行良好,但现在我试图重用它,它只是不发送证书,服务器回复:

HTTP/1.1 403 No client certificate supplied

How can I debug this and discover why the certificate is not being sent?我怎样才能调试这个并发现为什么没有发送证书?

Note : I implemented a similar call both in C# and using Postman , and in both cases it works perfectly, so the client certificate authentication to the server is working, it's just not working in my Java implementation.注意:我在C#Postman中都实现了一个类似的调用,在这两种情况下它都运行良好,所以对服务器的客户端证书身份验证工作正常,只是在我的 Java 实现中不起作用。

So, I don't know if this is a bug or intended behavior (if so, why?), but apparently the PFX file must be password-protected, then it gets sent correctly.所以,我不知道这是错误还是预期行为(如果是,为什么?),但显然 PFX 文件必须受密码保护,然后才能正确发送。 I could not make this work with a non-protected PFX file and passing null as the password like I was doing in the code I posted in the question.我无法使用不受保护的 PFX 文件并传递null作为密码,就像我在问题中发布的代码中所做的那样。

So the problem is solved, but I would be curious if anyone could comment on WHY this happens.所以问题解决了,但我很好奇是否有人可以评论为什么会发生这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM