繁体   English   中英

使用java代码和Apache CXF作为SOAP客户端时如何实现客户端认证?

[英]How to implement client authentication when using java code and Apache CXF as SOAP client?

我有一个使用 Apache CXF 创建的 SOAP Web 服务,该 CXF 托管在 Apache Z8F72E28063C30C4F9CFFB38 上。 一个网络服务器在它前面运行,并使用 AJP 协议将 web 服务请求转发给 Tomcat。

我的要求是在我通过网络服务器访问网络服务时进行客户端身份验证,以便只有授权的客户端才能连接到网络服务。

目前只发生服务器身份验证,当启用 SSL 时,我能够成功地进行 web 服务调用。

                URL wsdlURLStr = MyClassApiImpl.class.getResource("/wsdl/name-1.0.wsdl");
                JaxWsProxyFactoryBean proxyFactory = new  JaxWsProxyFactoryBean();
                ClientFactoryBean clientBean = proxyFactory.getClientFactoryBean();
                clientBean.setAddress(soapURL.toString());
                clientBean.setServiceClass(SPMLRequestPortType.class);
                clientBean.setWsdlURL(wsdlURLStr.toString());
                SpringBusFactory bf = new SpringBusFactory();
                URL cxfConfig = null;
                proxyFactory.setBus(bf.createBus(cxfConfig));
               
                m_endPoint = (SPMLRequestPortType) proxyFactory.create();
                Client deviceClient = ClientProxy.getClient(m_endPoint);
                HTTPConduit http = (HTTPConduit) deviceClient.getConduit();
              
                TLSClientParameters tlsCP = new TLSClientParameters();
                String keyPassword = "changeit";  
                java.security.cert.Certificate certca = getCACertificate(); //customcall
                java.security.cert.Certificate cert = getClientCertificate(); //customcall
                
                KeyStore keyStore = KeyStore.getInstance("JKS");
                keyStore.load(null, keyPassword.toCharArray());      
                keyStore.setCertificateEntry("clientCert", cert);
                KeyManager[] myKeyManagers = getKeyManagers(keyStore, keyPassword);
                tlsCP.setKeyManagers(myKeyManagers);
                KeyStore trustStore = KeyStore.getInstance("JKS");
                
                trustStore.load(null, keyPassword.toCharArray());
                trustStore.setCertificateEntry("caCrt", certca);
                TrustManager[] myTrustStoreKeyManagers = getTrustManagers(trustStore);
                tlsCP.setTrustManagers(myTrustStoreKeyManagers);
                tlsCP.setDisableCNCheck(true);
                http.setTlsClientParameters(tlsCP);
                 
                HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
                httpClientPolicy.setConnectionTimeout(36000);
                httpClientPolicy.setAllowChunking(false);
                httpClientPolicy.setReceiveTimeout(32000);
                http.setClient(httpClientPolicy);

以上是我从 java 客户端使用的代码。 如何进行客户端证书交换?

编辑:

当前的情况是仅发生服务器身份验证(仅使用信任库证书,我可以连接到托管在 HTTP 服务器后面的 web 服务)。 但看起来 CXF 支持指定自定义 SSLSocketFactory。 这可以强制我在 HTTP 服务器上进行任何配置的情况下交换客户端证书吗? 如果可行,我可能应该在我的 web 服务中执行一些逻辑来验证客户端。

我列出了我的代码中最终起作用的片段。

//....
Client deviceClient = ClientProxy.getClient(m_endPoint);
HTTPConduit http = (HTTPConduit) deviceClient.getConduit();              
TLSClientParameters tlsCP = new TLSClientParameters();
String keyPassword = "changeit";  
java.security.cert.Certificate certca = getCACertificate(); //customcall
java.security.cert.Certificate[] certchain = getClientCertificateChain(); //customcall

KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(null, keyPassword.toCharArray());
trustStore.setCertificateEntry("caCrt", certca);
TrustManager[] myTrustStoreKeyManagers = getTrustManagers(trustStore);
tlsCP.setTrustManagers(myTrustStoreKeyManagers);

KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(null, keyPassword.toCharArray());
PrivateKey key = getClientPrivateKey(); //custom call
keyStore.setKeyEntry("myKey", key, keyPassword.toCharArray(), certchain);       
KeyManager[] myKeyManagers = getKeyManagers(keyStore, keyPassword);
tlsCP.setKeyManagers(myKeyManagers); 

tlsCP.setDisableCNCheck(true);
tlsCP.setSecureSocketProtocol("TLSv1.2");
tlsCP.setCipherSuites(Collections.singletonList("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"));
http.setTlsClientParameters(tlsCP); 
           
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(36000);
httpClientPolicy.setAllowChunking(false);
httpClientPolicy.setReceiveTimeout(32000);
http.setClient(httpClientPolicy);
//...

我希望上面的代码没有任何安全问题。 在 Apache HTTP 服务器配置中,我执行了以下操作。 我禁用了 TLSv1.3。

SSLCACertificateFile "<cacert_that_issued_clientcert"
SSLVerifyClient require

暂无
暂无

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

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