我使用org.codehaus.mojo axistools-maven-plugin
插件版本1.4生成了代码。我正在尝试通过https连接到Web服务。我已将服务器证书安装到jssecacerts中,并将此密钥库复制到/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/
文件夹中。所以这意味着我在客户端密钥库中有服务器证书。我还将服务器私钥和证书导入到kestore.ImportKey密钥库中。我想我将不得不使用它作为信任存储。现在,如何在java客户端中将所有这些连接在一起?
我在客户端使用自动生成的存根。我尝试使用以下但不起作用。
System.setProperty("javax.net.ssl.trustStore","certs/keystore.ImportKey");
System.setProperty("javax.net.ssl.trustStorePassword", "importkey");
我得到以下异常。
faultString: javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
证书有效,因为我通过HTTPS客户端为同一主机使用相同的证书。此外,我能够看到成功的curl请求使用相同的证书。实际上,我不知道如何使用自签名服务器证书在https
上编写Axis2 soap Java客户端。任何人都可以指出我一步一步的例子。
答案 0 :(得分:2)
在客户端,您不需要证书私钥来信任服务器。由于您在问题中写道,您导入了keystore.ImportKey
中的证书和密钥,我认为它们已作为PrivateKeyEntry
导入(您可以使用keytool
验证密钥库中的条目类型)。
但是,如果要将证书用作信任锚,则应将证书导入为TrustedCertificateEntry
。可以使用keytool
:
keytool -importcert -trustcacerts -alias myTrustAnchor -file /path/to/cert.crt -keystore /path/to/keystore
然后,您可以在应用程序中配置信任库:
System.setProperty("javax.net.ssl.trustStore","/path/to/keystore");
答案 1 :(得分:2)
谢谢@Jcs
这就是我解决问题的方法。当我尝试在浏览器中打开Web服务URL时,它要求提供客户端证书。这意味着,因为我已经在jvm中的jssecacert
中导入了服务器证书,我的客户端缺少客户端证书。因此,我设置了javax.net.ssl.trustStore
和javax.net.ssl.trustStorePassword
属性,而不是设置javax.net.ssl.keyStore
和javax.net.ssl.keyStorePassword
属性,而且工作正常。在私钥和证书导入密钥库之前我错过了。 ImportKey
基本上是客户端身份,我从那些说服务器证书的人那里收到了很长时间。这误导了我。所以,如果有人正在寻找它,让我总结一下解决方案。
下载服务器证书并导入系统路径上的JVM cacerts或jssecacerts。 我使用了this post。
在浏览器中打开Web服务URL,如果要求提供客户端证书,则表示服务器设置为期望来自客户端的证书。如果是自签名证书,则必须已从服务器获得自签名证书。在密钥库中导入它们并在实际调用Web服务之前设置密钥库而不是信任库的系统属性,如下所示。这是因为您已将服务器证书导入客户端信任存储区(cacerts
)。
代码:
MySoap12Stub stub = (MySoap12Stub) new MyLocator().getMySoap12(new java.net.URL(WSUrl));
System.setProperty("javax.net.ssl.keyStore", "certs/keystoreQA.Importkey");
System.setProperty("javax.net.ssl.keyStorePassword", "importkey");
此外,在我的情况下,服务器期望将用户令牌和密码设置为SOAP头。这就是我将其设置为SOAP标头的方式:
((Stub) stub).setHeader(HeaderHandler.getSecurityHeader(User, password));
public class HeaderHandler {
public static SOAPHeaderElement getSecurityHeader(String user,String password) throws Exception {
SOAPHeaderElement wsseSecurity = new SOAPHeaderElement(new PrefixedQName(
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"Security", "wsse"));
wsseSecurity.setActor(null);
wsseSecurity.setMustUnderstand(true);
SOAPElement usernameToken = wsseSecurity.addChildElement("UsernameToken", "wsse");
usernameToken.setAttribute("xmlns:wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement username = usernameToken.addChildElement("Username", "wsse");
username.addTextNode(user);
SOAPElement password = usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
password.addTextNode(password);
return wsseSecurity;
}
}
我希望这详细解释如何在使用usertoken和密码通过https的axis2客户端调用Web服务中使用自签名证书和WSSE用户令牌和密码。
干杯!现在好了。