由于 java 中缺少证书(基于 XML SOAP),使用 Web 服务时出错
我需要使用在java中的Https下构建的Web服务。 Web 服务客户端是使用 Eclipse 生成的,并使用以下代码调用它:
ServicioTimbradoPruebasLocator ServicioTimbradoLocator = new ServicioTimbradoPruebasLocator();
ServicioTimbradoPruebasSoap ServicioTimbrado = ServicioTimbradoLocator.getServicioTimbradoPruebasSoap();
javax.xml.rpc.Stub s =((javax.xml.rpc.Stub)ServicioTimbrado);
s._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, "XXXXXXXX");
s._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, "psswd");
String resultado = ServicioTimbrado.generaTimbre(xml.getBytes());
System.out.println("resultado: " +resultado);
在这一行 String resultado = ServicioTimbrado.generaTimbre(xml.getBytes()); 我收到以下错误:
AxisFault
[java] faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
[java] faultSubcode:
[java] 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
[java] faultActor:
[java] faultNode:
[java] faultDetail:
[java] {http://xml.apache.org/axis/}stackTrace: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
[java] at sun.security.ssl.Alerts.getSSLException(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
[java] at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
[java] at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
[java] at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
[java] at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
[java] at sun.security.ssl.Handshaker.processLoop(Unknown Source)
[java] at sun.security.ssl.Handshaker.process_record(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
[java] at org.apache.axis.components.net.JSSESocketFactory.create(JSSESocketFactory.java:186)
[java] at org.apache.axis.transport.http.HTTPSender.getSocket(HTTPSender.java:191)
[java] at org.apache.axis.transport.http.HTTPSender.writeToSocket(HTTPSender.java:404)
[java] at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:138)
[java] at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
[java] at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
[java] at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
[java] at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
[java] at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
[java] at org.apache.axis.client.Call.invoke(Call.java:2767)
[java] at org.apache.axis.client.Call.invoke(Call.java:2443)
[java] at org.apache.axis.client.Call.invoke(Call.java:2366)
[java] at org.apache.axis.client.Call.invoke(Call.java:1812)
[java] at mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoapStub.generaTimbre(ServicioTimbradoPruebasSoapStub.java:107)
[java] at natura.facturacion.general.GuardarFacturaElectronicav2.doPost(GuardarFacturaElectronicav2.java:136) ...
我想要了解是否有办法通过 Web 服务调用发送证书。 有关 wsdl 合约和 java 生成的文件的更多信息可以在此处找到
I need to consume a web service which was built under Https in java.
The Web Service Client was generated using Eclipse and to call it I use the following code:
ServicioTimbradoPruebasLocator ServicioTimbradoLocator = new ServicioTimbradoPruebasLocator();
ServicioTimbradoPruebasSoap ServicioTimbrado = ServicioTimbradoLocator.getServicioTimbradoPruebasSoap();
javax.xml.rpc.Stub s =((javax.xml.rpc.Stub)ServicioTimbrado);
s._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, "XXXXXXXX");
s._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, "psswd");
String resultado = ServicioTimbrado.generaTimbre(xml.getBytes());
System.out.println("resultado: " +resultado);
On this line String resultado = ServicioTimbrado.generaTimbre(xml.getBytes()); I get the following error:
AxisFault
[java] faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
[java] faultSubcode:
[java] 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
[java] faultActor:
[java] faultNode:
[java] faultDetail:
[java] {http://xml.apache.org/axis/}stackTrace: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
[java] at sun.security.ssl.Alerts.getSSLException(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
[java] at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
[java] at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
[java] at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
[java] at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
[java] at sun.security.ssl.Handshaker.processLoop(Unknown Source)
[java] at sun.security.ssl.Handshaker.process_record(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
[java] at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
[java] at org.apache.axis.components.net.JSSESocketFactory.create(JSSESocketFactory.java:186)
[java] at org.apache.axis.transport.http.HTTPSender.getSocket(HTTPSender.java:191)
[java] at org.apache.axis.transport.http.HTTPSender.writeToSocket(HTTPSender.java:404)
[java] at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:138)
[java] at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
[java] at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
[java] at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
[java] at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
[java] at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
[java] at org.apache.axis.client.Call.invoke(Call.java:2767)
[java] at org.apache.axis.client.Call.invoke(Call.java:2443)
[java] at org.apache.axis.client.Call.invoke(Call.java:2366)
[java] at org.apache.axis.client.Call.invoke(Call.java:1812)
[java] at mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoapStub.generaTimbre(ServicioTimbradoPruebasSoapStub.java:107)
[java] at natura.facturacion.general.GuardarFacturaElectronicav2.doPost(GuardarFacturaElectronicav2.java:136) ...
I want to know if there is a way to send the certificate among with the webservice call.
More information about the wsdl contract and the java generated files could be found here
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据您使用的 Java 版本,1.6 JRE/JDK 的“最近”更新之一包括全局 CACerts(签署 SSL 证书的受信任机构,例如 Verisign)的重大更改,以包括一些新的周围的证书类型。
我建议升级到最新版本的 Java 以查看是否有效,如果无效,选项 2 是...
使用 SSLPoke.java 您可以找出缺少哪些证书,以及 InstallCert.java 按如下方式安装它们;
如果这仍然导致问题,您能否包含 sslpoke 的输出,示例用法;
如果所有这些都不起作用,并且您可以获得证书文件(crt),您可以使用 keytool 命令手动导入该文件(cacerts 是将在本地工作目录中创建的文件;确保将其移动到 java 安全文件夹中在你的 JRE/JDK 中);
keytool -import -trustcacerts -alias AddTrustExternalCARoot -file cetificate.crt -keystore cacerts
Depending on the version of Java you are using, one of the "recent" updates to the 1.6 JRE/JDK include a significant change in the global CACerts (the Trusted authority that signs SSL Certificats, for instance Verisign) to include some of the new certificate types that are around.
I recommend upgrading to the latest versions of Java to see if that works, if not, Option 2 is...
Using SSLPoke.java you can find out which certificates are missing, and the InstallCert.java to install them as follows;
If this still causes issues, can you include the output from sslpoke, example usage;
If ALL that doesnt work, and you can get the certificate file (crt) you can manually import the file using the keytool command (cacerts is a file that will be created in your local working directory; ensure you move it into the java security folder in your JRE/JDK);
keytool -import -trustcacerts -alias AddTrustExternalCARoot -file cetificate.crt -keystore cacerts
您可以参考这个帖子:如何使用 Apache HttpClient 处理无效的 SSL 证书?
当然这里有一个 WSDL SOAP Web 服务,那里有一个 Apache HTTP 客户端,但错误是相同的,您可以用相同的方式(或多种方式)处理它。
你可以:
第一个更容易(在大多数情况下),但您应该仅在发布之前使用它,否则您将很容易遭受“中间人攻击”。第二个(通常)是更好的选择。
这里有一个综合但解释良好的文档,对前面描述的这两点和代码示例进行了说明:
http://ws.apache.org/xmlrpc/ssl.html
You can refer to this thread: How to handle invalid SSL certificates with Apache HttpClient?
Of course here you have a WSDL SOAP Web Service, there you have an Apache HTTP Client, but the error is the same and you can handle it in the same way (or ways).
You can:
The 1st one is easier (in the most of the case), but you should use it ONLY before the release or you'll be easily exposed to a "Man in the middle attack". The 2nd (usually) a better choice.
Here there is a synthetic but well explained documantation to those 2 points described before with code samples:
http://ws.apache.org/xmlrpc/ssl.html