具有客户端Axis2存根的信任库的私有密钥库

时间:2013-01-18 09:33:39

标签: java axis2

我需要调用使用客户端证书的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;

我收到了不推荐使用X509KeyManager和SSLContext的消息。 甚至是link的代码 (我发现有关该主题的官方AXIS2文档)使用了这个已弃用的代码。 其次,此代码使用SSLSocketFactory,而协议需要ProtocolSocketFactory。

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

使用AXIS2 1.6.2 Java 5 工具jdeveloper 10.1.3

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

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

“ Apache Commons提供了便利,使我们能够自定义负责创建安全套接字的SSL套接字工厂。通过定制,我的意思是能够在SSL握手中使用用户信任库/密钥库。为此,我们需要扩展SecureProtocolSocketFactory接口。在我们的自定义套接字工厂实现中,用户将其密钥库/信任库与默认密钥库进行引用。 为此,Apache Commons提供了一个名为AuthSSLProtocolSocketFactory的参考实现类。

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

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

开头的行中使用authhttps对象。