【问题标题】:Issue with Lumesse Web Services and WSSE plain text securityLumesse Web 服务和 WSSE 纯文本安全问题
【发布时间】:2014-11-25 09:38:39
【问题描述】:

我们目前正在重新开发一个遗留项目,该项目利用 Lumesse 的 SOAP Web 服务,通过 HTTPS 调用。

http://developer.lumesse.com/Getting_Started

这是在 ASP.NET 应用程序中使用的;最初的开发人员(他早就离开了)从未利用提供的 WSDL,而是更喜欢手动构造请求并解析响应。虽然这完全是疯狂的,但这是从 .NET 使用时 Lumesse 的文档实际推荐的,因为他们的服务使用过时的 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

我们使用的 WSDL,由 Lumesse 提供:

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 的主要问题是安全节点下的时间戳节点。它将处理的无关 Nonce 节点,大概是因为它不是 Security 节点下的第一个节点?谁知道(这实际上是我第一次使用任何形式的 SOAP/WCF 哈哈!)。

所以,Timestamp 节点需要去。如果您需要使用标准绑定,如 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 />
  }

}

再次感谢。

【问题讨论】:

  • 我在 WSDL 中看不到安全信息,您确定这是正确的 URL 吗? WSDL 应该有一个 (对于 ws-*)。此外,在您的家庭滚动示例中,您将结束 getAdvertisements 标记定义为 >,第二个结束括号是错字吗?此外,您的第二个示例有一个 ActivityId 节点,而您的自制示例没有。
  • 这当然是-愚蠢的问题-我认为这将是一个很大的问题?更新了自制示例请求 XML。我刚刚尝试在没有 ActivityId 节点的情况下手动将我们的 SOAP XML 推送到 Lumesse,不会影响结果('wsse:FailedCheck')——当然,它可能会在以后发生!
  • 更新 - 刚刚尝试将 Nonce 和 Created 节点也输入到 UsernameToken 节点中。不高兴,同样的错误。
  • 缺少Nonce元素确实会导致问题,我一开始错过了。不幸的是,向其中添加 Nonce 并不像更改设置那么简单。您需要使用自定义绑定,并且可能必须手动构建肥皂包。至少这是我知道的唯一方法。你可以在这里stackoverflow.com/questions/896901/…weblog.west-wind.com/posts/2012/Nov/24/…找到更多信息。希望这能解决您的问题。
  • 是的,这很奇怪...如果您通过添加服务引用导入 WSDL,它会将其设置为基本绑定,永远不会与 WSSE 或 WS-* 一起使用。从我所见,您需要手动创建不幸的数据包。另外,从您的帖子中,我假设您了解 SoapUI,如果不了解,请了解它。处理这些事情的另一个好工具是 Fiddler。虽然,Fiddler 更适合 HTTP 请求,但它可以派上用场。

标签: c# web-services soap wse wsse


【解决方案1】:

我也在使用相同的 api 并且遇到了同样的问题。如果您向下滚动到本文底部:http://www.hanselman.com/blog/BreakingAllTheRulesWithWCF.aspxScott Hanselman 通过代码而不是通过配置删除时间戳。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-02
    • 2012-03-13
    • 2013-06-11
    • 2016-02-02
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多