2013-03-27 81 views
0

我正尝试使用GlassFish 3.1.2.2 w/Metro JAX-WS连接到合作伙伴Web服务,并且出现HTTP错误403.7 - 禁止:需要SSL客户端证书。GlassFish Metro客户端证书出站web服务调用失败

我已经导入我们的合作伙伴提供到GlassFish的密钥存储私钥:

$ keytool -importkeystore -srckeystore XXX.pfx -srcstoretype pkcs12 -destkeystore keystore.jks 
$ keytool -changealias -alias "le-75e085d7-0ceb-4734-ac52-0e64646924c8" -destalias "XXX" -keystore keystore.jks 
$ keytool -keypasswd -alias XXX -keystore keystore.jks 

我则在GlassFish的domain.xml中httpsOutboundKeyAlias属性设置为这个新的关键:

然后,当我做一个WS电话:

[#|2013-03-26T17:58:30.888-0700|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=137;_ThreadName=Thread-2;|#.: ---[HTTP request - https://XXX]--- 
Accept: text/xml, multipart/related 
Content-Type: text/xml; charset=utf-8 
SOAPAction: "http://XXX" 
User-Agent: Metro/2.2.0-1 (tags/2.2.0u1-7139; 2012-06-02T10:55:19+0000) JAXWS-RI/2.2.6-2 JAXWS/2.2 svn-revision#unknown 
<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body>[...]</S:Body></S:Envelope>-------------------- 
|#] 

[#|2013-03-26T17:58:31.847-0700|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=137;_ThreadName=Thread-2;|#.: ---[HTTP response - https://XXX - 403]--- 
null: HTTP/1.1 403 Forbidden 
Content-Length: 1913 
Content-Type: text/html 
Date: Wed, 27 Mar 2013 00:58:31 GMT 
Server: Microsoft-IIS/6.0 
X-Powered-By: ASP.NET 
[...] 
<h2>HTTP Error 403.7 - Forbidden: SSL client certificate is required.<br>Internet Information Services (IIS)</h2> 

我有这个配置工作o其他webservices,但不是由于某种原因这个...不知道IIS的行为是不同的?

我似乎能够精细连接使用curl呈现使用OpenSSL的来自合作伙伴的PFX文件转换成一个PEM客户端证书:

$ openssl pkcs12 -in XXX.pfx -out XXX.pem -nodes 
$ curl -vk -E XXX.pem -H "Accept: text/xml, multipart/related" -H "Content-Type: text/xml; charset=utf-8" -H "SOAPAction: \"http://XXX\"" -d @req.xml https://XXX 

所以不知道为什么的GlassFish /地铁未在提交客户端证书预计时尚。

关于我可能缺少什么或如何排除故障的任何想法/建议?

我试着设置-Djavax.net.debug = ssl,但字节在GlassFish日志中显示为单独的日志条目,所以它很难读。 我也尝试从容器外的独立Java程序运行它,但后来碰到classpath issues

谢谢

+0

当跟踪javax.net。debug = ssl我可以清楚地看到***证书请求,但Glassfish在***证书链之后不提供任何证书,因为它与其他实例连接到其他服务器。 – TheArchitect 2013-03-28 01:36:57

+0

我还验证了客户端证书链中的顶级CA与握手过程中服务器提供的证书颁发机构(1)之一相匹配,以及(2)GlassFish cacerts.jks信任库中的证书,因此我不知道为什么GlassFish是不出示客户证书... – TheArchitect 2013-03-28 01:38:43

回答

0

好了,在后人的情况下它可以帮助别人,将来别人: 我们把范围缩小到GlassFish中的错误。

我们得到了使用javax.net.ssl库的连接,因此无论出于何种原因GlassFish拒绝为该特定服务器提供配置的httpsOutboundKeyAlias。不清楚具体原因,因为它适用于其他人,但从ssl日志看来,它可能是因为IIS服务器为客户端证书提供了一长串Accepted CAs?有可能列表比预期长,或者GlassFish在将客户端证书CA与提供的列表相匹配时遇到问题?欢迎GlassFish开发者直接跟踪我,如果他们关心解决这个问题。

总之,在此期间,这里的代码,使其工作:

首先,使用所提供的客户端证书密钥存储创建一个自定义的SSL套接字工厂:

KeyStore ebKeyStore = KeyStore.getInstance("PKCS12"); 
    try (InputStream clientCertKeyInput = new FileInputStream(pfxFilePath)) { 
     ebKeyStore.load(clientCertKeyInput, passwdChars); 
    } 
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
    keyManagerFactory.init(ebKeyStore, passwdChars); 

    SSLContext sslCtx = SSLContext.getInstance("TLS"); 
    sslCtx.init(keyManagerFactory.getKeyManagers(), 
       null, // default javax.net.ssl.trustStore 
       new SecureRandom()); 

    sslSocketFactory = sslCtx.getSocketFactory(); 

然后使SOAP堆栈在港口的RequestContext使用的SSLSocketFactory通过属性:

Map<String, Object> ctxt = ((BindingProvider) port).getRequestContext(); 
    ctxt.put(JAXWSProperties.SSL_SOCKET_FACTORY, sslSocketFactory); 

一线希望是GlassFish中的这种方法来提供客户端证书未如果您需要连接到多个对外方,那么至少可以解决这个问题。 :)

相关问题