简体   繁体   English

jersey-client 2.22.2 - 如何正确设置SslConfigurator上的SunPKCS11密钥库?

[英]jersey-client 2.22.2 - How to set SunPKCS11 keystore on SslConfigurator properly?

I have been attempting to have my jersey client do a ssl client authentication with my Jersey/Grizzly Rest api. 我一直试图让我的泽西客户端使用我的Jersey / Grizzly Rest api进行ssl客户端身份验证。 Other clients are successful handshaking with this server, but I am having trouble with my java client using Jersey client. 其他客户端与此服务器成功握手,但我使用Jersey客户端的java客户端遇到问题。 When I run the code below, the keystore is successfully loaded and when the SslConfigurator's createSSLContext() is called, the ssl debug output shows this keystore properly being accessed and my private keys found. 当我运行下面的代码时,密钥库已成功加载,并且当调用SslConfigurator的createSSLContext()时,ssl调试输出显示正确访问此密钥库并找到我的私钥。

However, when the Client's WebTarget is used, the ssl debug output shows the handshake is happening with the default keystore JKS. 但是,当使用客户端的WebTarget时,ssl调试输出显示使用默认密钥库JKS进行握手。 Why isn't the ClientBuilder using this keystore from the SSLContext? 为什么ClientBuilder不使用SSLContext中的这个密钥库?

File tmpConfigFile = File.createTempFile("pkcs11-", "conf");
        tmpConfigFile.deleteOnExit();
        PrintWriter configWriter = new PrintWriter(new FileOutputStream(tmpConfigFile), true);
        configWriter.println("name=ActiveClient");
        configWriter.println("library=\"C:\\\\Program Files\\\\ActivIdentity\\\\ActivClient\\\\acpkcs211.dll\"");
        configWriter.println("slotListIndex=0");
        SunPKCS11 provider = new SunPKCS11(tmpConfigFile.getAbsolutePath());
        Security.addProvider(provider);
        //  KeyStore keyStore = KeyStore.getInstance("PKCS11", provider);

        KeyStore keyStore = KeyStore.getInstance("PKCS11");
        keyStore.load(null, null);

        ClientConfig config = new ClientConfig();

        SslConfigurator sslConfig = SslConfigurator.newInstance()
                .keyStore(keyStore)
                .keyStorePassword("mypin")
                .keyStoreType("PKCS11")
                .trustStoreFile(TRUSTORE_CLIENT_FILE)
                .trustStorePassword(TRUSTSTORE_CLIENT_PWD)
                .securityProtocol("TLS");



        final SSLContext sslContext = sslConfig.createSSLContext();

        Client client = ClientBuilder
                .newBuilder().hostnameVerifier(new MyHostnNameVerifier())
                .sslContext(sslContext)
                .build();
        WebTarget target = client.target("https://localhost:8443/appname/resources/employees?qparam=something");  
     Response res = target.request().accept(MediaType.APPLICATION_JSON).get();

This code actually worked. 这段代码确实有效。 The problem was that my server's trust certificate wasn't available for the smart card cert that it needed to trust. 问题是我的服务器的信任证书不适用于它需要信任的智能卡证书。 I added the correct certs to the truststore on the server and then it worked. 我将正确的证书添加到服务器上的信任库,然后它工作。 The ssl debug messages weren't very clear. ssl调试消息不是很清楚。

I've run into many issues this time and I found a way to achieve my goals. 这次我遇到了很多问题,我找到了实现目标的方法。 In your example I can not see any use of ClientConfig config instance. 在您的示例中,我看不到任何ClientConfig config实例的使用。 This worked for me: 这对我有用:

    ClientConfig config = new ClientConfig();
    config.connectorProvider(new ApacheConnectorProvider());
    Client client = ClientBuilder.newBuilder().hostnameVerifier(new MyHostnNameVerifier())
            .sslContext(sslContext).withConfig(config).build();

I found ApacheConnectorProvider more suitable for connections using secure layers or proxies (witch was another huge problem I solved). 我发现ApacheConnectorProvider更适合使用安全层或代理的连接(这是我解决的另一个巨大问题)。

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

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