我们目前正在重新开发一个旧项目,该项目使用来自Lumesse的SOAP Web服务(通过HTTPS调用)。
http://developer.lumesse.com/Getting_Started
这在ASP.NET应用程序中正在使用。最初的开发人员(已离开公司很久了)从未利用过所提供的WSDL,而是倾向于手动构造请求并解析响应。尽管这很疯狂,但这是Lumesse的文档在从.NET中使用时的实际建议,因为他们的服务使用了过时的WSSE纯文本安全性。
尽管我们通常不反对,但我们更喜欢使用内置支持来使用SOAP Web服务,而不是像以前的开发人员那样使用自己的解决方案。
我们已经遇到了一些问题,例如无法生成我们一直在研究的临时类。
不幸的是,在发送成功的SOAP请求方面,我们现在陷入困境。
我们发出请求时抛出的异常是:The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
深入研究,实际响应如下:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header />
<env:Body>
<env:Fault xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">wsse:FailedCheck</faultcode>
<faultstring>Expired message.</faultstring>
</env:Fault>
</env:Body>
</env:Envelope>
看来是“签名或解密无效”。使用其他开发人员的共同解决方案,并且具有相同的凭据,可以正常工作。
为什么这里会失败,我们该怎么解决?
是否可以不依靠我们自己的请求和响应(甚至推荐?)服务滚动?
http://schemas.xmlsoap.org/specs/ws-security/ws-security.htm
由Lumesse提供的我们使用的WSDL:
https://api3.lumesse-talenthub.com/CareerPortal/SOAP/FoAdvert?WSDL
我们达到的终点:
https://api3.lumesse-talenthub.com/CareerPortal/SOAP/FoAdvert?api_key=xxx
到目前为止,这是我们的代码,很大程度上基于With C#, WCF SOAP consumer that uses WSSE plain text authentication?-看起来像是同一问题。
Correct way communicate WSSE Usernametoken for SOAP webservice具有相同的问题,但答案是我们将绑定详细信息存储在web.config中。
using (LumesseSoapTest.FoAdvert.FoAdvertWebServiceClient client = new LumesseSoapTest.FoAdvert.FoAdvertWebServiceClient())
{
client.ClientCredentials.UserName.UserName = "xxxx";
client.ClientCredentials.UserName.Password = "xxxx";
var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
client.Endpoint.Binding = binding;
var response = client.getAdvertisements(new LumesseSoapTest.FoAdvert.getAdvertisements());
}
Lumesse期望的示例请求(取自以前的开发人员自行开发的解决方案的一部分)-按预期工作:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.mrted.com/">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-11">
<wsse:Username>xxxx</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
xxxx
</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">5Xhsv3Yp2l1xGpL3pNYy6A==
</wsse:Nonce>
<wsu:Created>2012-06-22T09:07:26.631Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<getAdvertisements xmlns="http://ws.mrted.com/">
<firstResult>0</firstResult>
<maxResults>0</maxResults>
</getAdvertisements>
</soapenv:Body>
</soapenv:Envelope>
我们当前正在发送的示例请求:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<ActivityId CorrelationId="d309ce44-ed91-4314-87ee-e3abee4f531e" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">dd9a8c26-e673-464d-87e4-5cb8b76989c3</ActivityId>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2014-09-30T16:15:47.426Z</u:Created>
<u:Expires>2014-09-30T16:20:47.426Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-c3275c63-6d98-4ae3-a7a7-afe314d23d6c-3">
<o:Username>xxxx</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">xxxx</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<getAdvertisements xmlns="http://ws.mrted.com/">
<firstResult>0</firstResult>
<maxResults>0</maxResults>
</getAdvertisements>
</s:Body>
</s:Envelope>
任何帮助将不胜感激。
更新资料
正确,使用这种黑在一起的XML,我可以从API得到响应。
我只是不知道如何根据我们的要求生成此信息。同样,任何帮助将不胜感激。
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken u:Id="UsernameToken-11">
<o:Username>xxx</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">xxx
</o:Password>
<o:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
5Xhsv3Yp2l1xGpL3pNYy6A==
</o:Nonce>
<o:Created>2012-06-22T09:07:26.631Z</o:Created>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<getAdvertisements xmlns="http://ws.mrted.com/"><firstResult>0</firstResult><maxResults>10</maxResults>
</getAdvertisements>
</s:Body>
</s:Envelope>
更新2(让它正常工作!)
终于,大约9个小时后,我们到达了某个地方。我将把这留给所有有与Lumesse(或另一个类似的Java Web服务)合作的不幸的人。
我们上面发送的XML的主要问题是Security节点下的Timestamp节点。它会处理无关的Nonce节点,大概是因为它不是Security节点下的第一个节点吗?谁知道(这实际上是我对SOAP / WCF的任何形式的第一次体验哈哈!)。
因此,时间戳节点需要运行。如果您需要使用诸如basicHttpBinding之类的标准绑定
或wsHttpBinding,则需要创建一个自定义绑定。这是一个模仿basicHttpBinding的示例,显然取自http://www.mikeobrien.net/blog/removing-wss-timestamp-from-wcf/
配置示例:
<customBinding>
<binding name="MyBinding">
<security authenticationMode="UserNameOverTransport" includeTimestamp="false" />
<textMessageEncoding messageVersion="Soap11" />
<httpsTransport maxReceivedMessageSize="26214400" />
</binding>
</customBinding>
然后只需调用该服务,传入凭据即可(您可以将这些凭据与上面的凭据一起存储在web.config中,但是如果我知道该怎么做的话,我现在就该死了)。
using (LumesseSoapTest.FoAdvert.FoAdvertWebServiceClient client = new LumesseSoapTest.FoAdvert.FoAdvertWebServiceClient())
{
client.ClientCredentials.UserName.UserName = "xxxx";
client.ClientCredentials.UserName.Password = "xxxx";
foreach (var ad in response.advertisementResult.advertisements)
{
@ad.jobTitle <br />
}
}
再次感谢。
最佳答案
我也正在使用相同的api,并且遇到了相同的问题。如果您滚动到本文的底部,请执行以下操作:http://www.hanselman.com/blog/BreakingAllTheRulesWithWCF.aspx Scott Hanselman通过代码而不是通过配置删除时间戳记。
关于c# - Lumesse Web Services和WSSE纯文本安全性问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26126257/