2

我需要调用使用客户端证书的 Web 服务。该程序将由不同的客户使用,每个客户都有自己的证书。客户端证书用于身份验证,因此客户端只能看到自己的数据。因此,对该 Web 服务的每次调用都必须使用其特定的密钥库。

Axis2 用于生成客户端代码。我发现这段代码可以将 SocketFactory 设置为存根的特定实例。

int x = 9443;
Protocol authProtocol;
authProtocol = 
      new Protocol("https",
                   setPrivateKey(keyStoreFileName,keyStoreType, keyStorePassword),
                   x
                  );
stub._getServiceClient().getOptions().setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER, authProtocol);

然后 SocketFactory 将是

private static SSLSocketFactory setPrivateKey
  (String keyStoreFileName,
   String keyStoreType,
   String keyStorePassword
  ) 
  throws FileNotFoundException, 
         KeyStoreException, 
         IOException, 
         NoSuchAlgorithmException, 
         CertificateException, 
         UnrecoverableKeyException, 
         KeyManagementException
  {
    // Load the key store: change store type if needed
    KeyStore ks = KeyStore.getInstance(keyStoreType);
    FileInputStream fis = new FileInputStream(keyStoreFileName);
    try {
        ks.load(fis, keyStorePassword.toCharArray());
    } finally {
        if (fis != null) { fis.close(); }
    }
    // Get the default Key Manager
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(
       KeyManagerFactory.getDefaultAlgorithm());   
    kmf.init(ks, keyStorePassword.toCharArray());
     X509KeyManager origKm = (X509KeyManager)kmf.getKeyManagers()[0];
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(new KeyManager[] {origKm }, null, null);

    return sslContext.getSocketFactory();
}

使用以下进口

import com.sun.net.ssl.KeyManager;
import com.sun.net.ssl.SSLContext;
import com.sun.net.ssl.X509KeyManager;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.SocketFactory;
import javax.net.ssl.KeyManagerFactory;

import javax.net.ssl.SSLSocketFactory;

import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.xmlbeans.XmlException;

我收到 X5​​09KeyManager 和 SSLContext 已弃用的消息。甚至此链接中的代码 (我通过有关该主题的官方 AXIS2 文档找到)也使用了此已弃用的代码。其次,此代码使用 SSLSocketFactory,而协议需要一个 ProtocolSocketFactory。

X509KeyManager 和 SSLContext 的替代品是什么?以及如何从密钥库到 ProtocolSocketFactory?或者,还有更好的方法。

使用 AXIS2 1.6.2 Java 5 工具 jdeveloper 10.1.3

编辑 22-01-2013 被调用的 web 服务属于不同的组织,我无法控制 web 服务的服务器端。

“不同客户使用”是我们软件的不同用户。位于 1 个中心点。

4

2 回答 2

0

我假设“由不同的客户使用”意味着不同的部署。在这种情况下,真的有必要以编程方式选择正确的密钥库吗?是否可以使用多个不同的密钥库(每个用于一个客户端)并让应用程序服务器/servlet 容器处理客户端证书?例如对于 Apache Tomcat,这可以CATALINA_OPTS="$CATALINA_OPTS -Djavax.net.ssl.keystore=<the keystore filename>"在启动服务器之前实现设置。然后,您可以像往常一样为简单的 http Web 服务创建客户端 WS,而无需授权。Tomcat 使用证书以完全透明的方式处理与客户端身份验证的 SSL 连接。

于 2013-01-21T22:52:49.327 回答
0

博客http://shivendra-tripathi.blogspot.com/2010/11/enabling-ssl-for-axis2-service-and.html在标题方法 2 下给出了您问题的答案:

“Apache commons 提供了允许我们自定义负责创建安全套接字的 SSL 套接字工厂的工具。自定义是指在 SSL 握手中使用用户信任库/密钥库的能力。为了实现它,我们需要扩展 SecureProtocolSocketFactory 接口。在我们的自定义套接字工厂实现中,用户将其 Keystore/Truststore 与默认密钥库进行对比。Apache commons 为此提供了一个名为 AuthSSLProtocolSocketFactory 的参考实现类。

此类将 Truststore/Keystore 作为构造函数的参数,稍后将在启动 SSLContext 时引用。SSLContext 用于创建 SSL 套接字工厂。在您的axis2客户端代码中,您需要添加以下内容: Protocol authhttps = new Protocol ("https", new AuthSSLProtocolSocketFactory (new url("keystore URL"), "pwd", newURL("truststore URL"), "pwd"), 443);”</p>

在以 stub._getServiceClient().getOptions().setProperty(HTTPConsta...

于 2018-08-24T11:20:12.363 回答