从 JAXWS-RI 调用 .NET Web 服务(WSE 3.0、WS-Security)
我正在编写一个 JAXWS-RI 客户端,它必须调用使用 WS-Security 的 .NET Web 服务。该服务的 WSDL 不包含任何 WS-Security 信息,但我有来自服务作者的示例肥皂消息,并且知道我必须包含 wsse:Security 标头,包括 X:509 令牌。
我一直在研究,并且见过人们从 Axis 和 CXF(与 Rampart 和/或 WSS4J 结合)调用此类 Web 服务的示例,但没有看到关于使用普通 JAXWS-RI 本身的情况。然而,我(不幸的是)被我的政府客户限制使用 JAXWS-RI。有人有 JAXWS-RI 执行此操作的示例/文档吗?
我需要最终生成一个类似于下面的 SOAP 标头 - 这是来自服务作者编写的 .NET 客户端的示例soap:header。 (注意:我已将“VALUE_HERE”字符串放在需要提供自己的值的地方)
<soapenv:Envelope xmlns:iri="http://EOIR/IRIES" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-wssecurity-secext-1.0.xsd">
<xenc:EncryptedKey Id="VALUE_HERE">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">
VALUE_HERE
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>VALUE_HERE</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#EncDataId-8"/>
</xenc:ReferenceList>
</xenc:EncryptedKey>
</wsse:Security>
I'm writing a JAXWS-RI client that must call a .NET Web Service that is using WS-Security. The service's WSDL does not contain any WS-Security info, but I have an example soap message from the service's authors and know that I must include wsse:Security headers, including X:509 tokens.
I've been researching, and I've seen example of folks calling this type of web service from Axis and CXF (in conjunction with Rampart and/or WSS4J), but nothing about using plain JAXWS-RI itself. However, I'm (unfortunately) constrained to using JAXWS-RI by my gov't client. Does anyone have any examples/documentation of doing this from JAXWS-RI?
I need to ultimately generate a SOAP header that looks something like the one below - this is a sample soap:header from a .NET client written by the service's authors. (Note: I've put the 'VALUE_HERE' string in places where I need to provide my own values)
<soapenv:Envelope xmlns:iri="http://EOIR/IRIES" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-wssecurity-secext-1.0.xsd">
<xenc:EncryptedKey Id="VALUE_HERE">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">
VALUE_HERE
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>VALUE_HERE</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#EncDataId-8"/>
</xenc:ReferenceList>
</xenc:EncryptedKey>
</wsse:Security>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试使用 a 配置您的端口,
的自定义实现
它使用接受 a
,并且
您从类路径上的资源加载。我刚刚在这里写了一篇博客: http:// /upthescala.blogspot.com/2010/03/essential-sources-for-jax-ws-x509.html 。
有关配置端口(包括从文件加载私钥和 X.509 证书)的示例,请参阅 com.sun.xml.ws.commons.EC2(在上述博客条目中链接的源下载中)。
我会发布更多代码,但我没有带开发盒,所以我无法真正进行测试。
祝你好运!
Try configuring your port with a
That uses a custom implementation of
that accepts a
and
that you load from a resource on your classpath. I just blogged about this here: http://upthescala.blogspot.com/2010/03/essential-sources-for-jax-ws-x509.html .
See com.sun.xml.ws.commons.EC2 (in the source download linked in the blog entry noted above) for an example of configuring the port (including loading the private key and X.509 certs from a file).
I'd post more code but I don't have my dev box with me so I can't really test.
Good luck!
经过一段时间的研究后,我们的开发团队确定我们无法做到这一点。我们根本无法编写一个能够正确调用 & 的 Metro(JAXWS-RI+WSIT) 客户端。处理来自使用 WS-Security 的 .NET WSE 3.0 Web 服务的响应。不过,我想为那些将来可能尝试类似方法的人写下我们的不同方法。
回顾一下:
1. 我们的第一遍:具有 MutualCerticates11 安全性的 WSE 3.0 Web 服务(WS-寻址、加密、签名、安全对话 (ws-trust))。我们对 WS-Policy 片段进行了逆向工程,将其放置在 WSDL 的本地副本中来处理此问题,但无法让 WSE 接受安全对话初始握手请求。
接下来,他们降级到 WSE 3.0 MutualCerticates10,因为有人议论它“更具互操作性”。同样,我们无法让安全对话握手发挥作用。
我们要求 .NET 团队关闭 SecureConversation (WS-Trust) 层(加密和签名要求仍然存在)。我们再次对 WS-Policy 文件进行逆向工程(本质上,只是删除了处理 WS-Trust/SC 的“BootstrapPolicy”部分)。此时,我们能够向他们发送加密的签名消息,他们收到该消息并发回消息。我们认为这是一次胜利,但不幸的是,WSIT 因规范化错误而被他们的响应消息噎住了。此时,我认为我们遇到了 WSIT 的局限性,因为它没有声称可以与 WSE 3.0(仅限 WCF)互操作,因此我们在论坛上与 WSIT 人员进行了交谈,并向他们记录了一个问题。这是链接。
因此,我们得出的结论是,.NET 团队不可能保留加密/签名层(无论如何,目前 - WSIT 团队可能会在某个时候修复该错误)。不幸的是,从他们的角度来看,您不能仅关闭签名并保留加密。
我们还要求他们完全关闭其 (.NET) 端的 WS-Security 设置,此时我们就能够发送请求和请求了。使用 JAXWS-RI 从他们的服务接收响应就好了。但是,他们可能无法在生产中以这种方式进行部署。
现在,.NET 团队必须确定他们是否可以在没有 WS-Security 设置的情况下在生产环境中运行 Web 服务。如果没有,那么我们将无法连接到他们的服务,直到他们升级到 WCF。事实上,这一直是我们向他们的建议 - 他们升级到 WCF - 现在我们比我们想要的更熟悉其中的原因!
After working on this for quite a while, our team of developers here has determined that we couldn't do this. We simply could not write a Metro(JAXWS-RI+WSIT) client that would correctly call & process a response from the .NET WSE 3.0 web service that used WS-Security. I wanted to write up our different approaches, though, for those who might try something like this in the future.
To recap:
1. Our first pass: WSE 3.0 web service with MutualCerticates11 Security (WS-Addressing, encryption, signing, secure conversation (ws-trust)). We reverse engineered a WS-Policy snippet to place in our local copy of the WSDL to hande this, but could not get the secure conversation initial handshake request to be accepted by WSE.
Next, they downgraded to WSE 3.0 MutualCerticates10, as there is some chatter about it being 'more interoperable'. Again, we could not get the secure conversation handshake to work.
We asked the .NET team to turn off the SecureConversation (WS-Trust) layer (the encyption & signature requirements where still there). Again, we reverse engineered the WS-Policy file (essentially, just removed the 'BootstrapPolicy' section that deals with WS-Trust/SC). At this point, we were able to send an encrypted, signed message to them, and they recieved it and sent a message back. We thought this was a victory, but unforunately, WSIT choked on their response message with a canonicalization error. At this point, I think we hit the limitations of WSIT, as it does not claim to be interoperable with WSE 3.0 (only WCF), so we talked to the WSIT guys on their forum and logged an issue with them. Here's that link.
So, we concluded that it wouldn't be possible for the .NET team to leave the encryption/signature layer on (for the moment, anyway - the WSIT team may fix the bug at some point). From their side, you can't turn off just the signature and leave encryption, unfortunately.
We also asked them to turn off the WS-Security settings on their (.NET) side completely, and at that point, were are able to send requests & receive responses from their service using JAXWS-RI just fine. However, they may not be able to deploy this way in production.
So, now we are at the point where the .NET team must determine if they will be allowed to run the web service in production w/o the WS-Security settings. If not, then we will not be able to connect to their service until they upgrade to WCF. And, in fact, that has been our recommendation to them all along - that they upgrade to WCF - and now we're more familiar than we'd like to be about the reasons why!
我仍在解决一些问题,试图解决这个问题,但我想更新我已经决定的方法的一些细节。我意识到的第一件事是我必须从使用 JAXWS-RI 2.1 升级到 Metro 2.0。我们之前曾在此项目中使用过 JAXWSRI-2.1,但之前我们从未处理过任何 WS-Security。不管怎样,我意识到我需要升级,所以我这样做是为了利用 Metro 2.0 和其中包含的 WSIT jar。然后,我仍然对如何生成我需要的 WS-Security 标头感到困惑,而无需从服务的 WSDL 文件中获取 WS-Policy 信息。我曾尝试使用 LES2 建议的 API 设置 CallbackHandlerFeature,但这并没有为我生成标头。因此,我在 java.net 的 Metro/JAXB 板上发布了一个问题:
http://forums.java.net/jive/message.jspa?messageID=392451#392451
在对此的回复中,一位回答者建议使用 NetBeans 编写一个虚拟 Web 服务并设置安全设置我认为 .NET 的服务正在使用。完成此操作后,NetBeans 在 wsit-.xml 文件中生成了一个我可以使用的 WS-Policy 部分。我将该 WS-Policy 部分插入到 .NET 服务 WSDL 的本地副本中,并使用它创建了一个 wsit-client.xml 文件,并将其放入 WEB-INF/classes 目录中。
一旦我这样做了,Metro/WSIT 就开始添加 WS-Security 标头来请求我。然后我遇到了一些问题,因为 Metro 使用的 WS-Addressing 版本与 .NET 服务所需的版本不同(它们使用 MemberSubmissionAddressing)。因此,我最终调整了 WS-Policy 设置以使用
现在,我的 SOAP 请求如下所示:
而且,虽然这与 . NET 团队,我认为这是正确的。但是,当我调用 .NET 服务时仍然收到错误。这是从他们那里返回的 SOAPFault 错误消息:
System.Web.Services.Protocols.SoapHeaderException: Server unavailable, please try later ---> System.ApplicationException:WSE841:处理传出故障响应时发生错误。 ---> System.Web.Services.Protocols.SoapHeaderException:Microsoft.Web.Services3.Security.SecurityFault:无法对安全令牌进行身份验证或授权 ---> System.Security.SecurityException:WSE3003:无法验证证书的信任链。请检查证书是否已正确安装在受信任的人证书存储中。或者您可能想将allowTestRoot配置部分设置为
如果这是测试证书,则为 true。
因此,我目前正在与他们合作,找出为什么无法验证证书的信任链 - 我不清楚这个特定问题是我的问题还是他们的问题。任何建议将不胜感激!
I am still working through some issues trying to solve this issue, but I wanted to update with some details of the approach I've settled on. The first thing that I realized was that I had to upgrade from using JAXWS-RI 2.1 to Metro 2.0. We had previously used JAXWSRI-2.1 in this project, but we'd never had to deal with any WS-Security before. Anyway, I realized that I needed to upgrade, so I did that to take advantage of Metro 2.0 and the WSIT jars that were included with it. Then, I was still confused about exactly how to do about generating the WS-Security headers that I needed w/o having the WS-Policy info from the service's WSDL file. I had attempted to set a CallbackHandlerFeature using the APIs suggested by LES2, but that was not generating the headers for me. So, I posted a question on the Metro/JAXB board at java.net here:
http://forums.java.net/jive/message.jspa?messageID=392451#392451
In the responses to that, one answerer suggested using NetBeans to write a dummy web service and set up the security settings that I though the .NET's service was using. Once I did that, NetBeans generated a WS-Policy section in the wsit-.xml file that I could use. I plugged that WS-Policy section into my local copy of the .NET service's WSDL, and also used it to create a wsit-client.xml file that I put in my WEB-INF/classes directory.
Once I did that, Metro/WSIT began adding the WS-Security headers to request for me. I was then running into some issues, because Metro was using a different version of WS-Addressing than was required by the .NET service (they use MemberSubmissionAddressing). So, I ended up tweaking my WS-Policy settings to use
Now, I'm at the point where I've got my SOAP request looking like this:
And, while that doesn't exactly match the sample given to me by the .NET team, I think it that it is correct. However, I'm still getting an error when I call the .NET service. This is the error message that comes back in a SOAPFault from them:
System.Web.Services.Protocols.SoapHeaderException: Server unavailable, please try later ---> System.ApplicationException: WSE841: An error occured processing an outgoing fault response. ---> System.Web.Services.Protocols.SoapHeaderException: Microsoft.Web.Services3.Security.SecurityFault: The security token could not be authenticated or authorized ---> System.Security.SecurityException: WSE3003: The certificate's trust chain could not be verified. Please check if the certificate has been properly installed in the Trusted People Certificate store. Or you might want to set allowTestRoot configuration section to
true if this is a test certificate.
So, I'm currently working with them to figure out why the certificate's trust chain can't be verified - I'm unclear on whether that particular issue is on my end or theirs. Any suggestions would be appreciated!