我已经用Java创建了一个Web服务,它将数据发布到另一个Web服务。这需要SSL证书进行身份验证。这个Web服务在Tomcat上正常运行,但是当我在GlassFish 3.0.1服务器上部署相同的代码时,我得到javax.net.ssl.SSLHandshakeException
:收到致命警报:未知的ca异常。
我已使用keytool将证书导入glassfish trustStore。所需证书由客户提供。
我的代码:
System.setProperty("javax.net.ssl.keyStoreType" , "pkcs12");
System.setProperty("javax.net.ssl.keyStore", applicationRootDirPath + "clientCert.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
System.setProperty("javax.net.ssl.trustStoreType", "jks");
System.setProperty("javax.net.ssl.trustStore", "path of glass fish truststore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
try {
url = new URL(serverUrl);
urlConn = url.openConnection();
urlConn.setDoOutput(true);
urlConn.setRequestMethod("POST");
urlConn.setAllowUserInteraction(false);
urlConn.setUseCaches(false);
urlConn.setRequestProperty("Content-type", "text/xml; charset=utf-8");
urlConn.setRequestProperty("Content-Length", new Integer(xml.length()).toString());
try {
writer = new OutputStreamWriter(urlConn.getOutputStream(), "UTF-8");
writer.write(xmlData);
} finally {
if (writer != null) {
writer.close();
}
}
trace += "\n urlConn.getInputStream()";
in = urlConn.getInputStream();
}
答案 0 :(得分:0)
您使用的开发环境是什么?如果您使用的是NetBeans,则必须在/etc/netbeans.conf
中的VMargs中设置这些(这是正确的Web服务工具功能所必需的,以便您可以生成客户端):
<NETBEANS_HOME>/bin/netbeans.exe
-J-Djavax.net.ssl.trustStore=<AS_HOME>/domains/domain1/config/cacerts.jks
-J-Djavax.net.ssl.keyStore=<AS_HOME>/domains/domain1/config/keystore.jks
-J-Djavax.net.ssl.trustStorePassword=changeit
-J-Djavax.net.ssl.keyStorePassword=changeit
另外,请确保您已正确设置GlassFish中的信任库;将这些行完全添加到JVM选项中:
-Djavax.net.ssl.trustStore=${truststore.location}
-Djavax.net.ssl.trustStorePassword=${ssl.password}
此外,如果它不是有效证书(例如主机名不匹配,这是javax.net.ssl.SSLHandshakeException
的常见原因),您可以在客户端Web服务中进行解决方法以进行开发/测试:
static {
//WORKAROUND. TO BE REMOVED.
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){
public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("mytargethostname")) { //Change to actual value
return true;
}
return false;
}
});
}
目前我没有看到您问题的根源,但这些是我认为您应该解决的问题。
答案 1 :(得分:0)
您还需要指定以下JVM选项:
-Dcom.sun.enterprise.security.httpsOutboundKeyAlias=[alias of the client certificate in your keystore]