【问题标题】:Configuring a WCF Client to Use UserName Credentials On the Request and Check Certificate Credentials On the Response将 WCF 客户端配置为在请求中使用用户名凭据并在响应中检查证书凭据
【发布时间】:2023-04-08 12:53:01
【问题描述】:

我正在尝试使用 WCF 来使用第三方 Oracle 应用服务器提供的 Web 服务。我在 UsernameToken 中传递用户名和密码作为请求的一部分,作为响应的一部分,Web 服务在标头中返回一个标准安全标记,其中包括摘要和签名。

使用我当前的设置,我成功地向服务器发送了一个请求,Web 服务将预期的响应数据发回。但是,在解析响应时,WCF 会抛出 MessageSecurityException,并带有 InnerException.Message “不期望支持令牌签名”。

我的猜测是 WCF 希望我配置它来处理签名并验证它。我有一个托管 Web 服务的第三方的证书,我应该可以使用它来验证签名,但我不确定是否需要它。

下面是一个让 WCF 抛出异常的响应的示例标头:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <dsig:Signature xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
        <dsig:SignedInfo>
          <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
          <dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
          <dsig:Reference URI="#_51IUwNWRVvPOcz12pZHLNQ22">
            <dsig:Transforms>
              <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </dsig:Transforms>
            <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <dsig:DigestValue>
              [DigestValue here]
            </dsig:DigestValue>
          </dsig:Reference>
          <dsig:Reference URI="#_dI5j0EqxrVsj0e62J6vd6w22">
            <dsig:Transforms>
              <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </dsig:Transforms>
            <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <dsig:DigestValue>
              [DigestValue here]
            </dsig:DigestValue>
          </dsig:Reference>
        </dsig:SignedInfo>
        <dsig:SignatureValue>
          [Signature Value Here]
        </dsig:SignatureValue>
        <dsig:KeyInfo>
          <wsse:SecurityTokenReference xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <wsse:Reference URI="#BST-9nKWbrE4LRv6maqstrGuUQ22" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
          </wsse:SecurityTokenReference>
        </dsig:KeyInfo>
      </dsig:Signature>
      <wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" wsu:Id="BST-9nKWbrE4LRv6maqstrGuUQ22" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        [Security Token Here]
      </wsse:BinarySecurityToken>
      <wsu:Timestamp wsu:Id="_dI5j0EqxrVsj0e62J6vd6w22" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsu:Created>2010-05-26T18:46:30Z</wsu:Created>
      </wsu:Timestamp>
    </wsse:Security>
  </soap:Header>
  <soap:Body wsu:Id="_51IUwNWRVvPOcz12pZHLNQ22" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    [Body content here]
  </soap:Body>
</soap:Envelope>

我的绑定配置如下:

<basicHttpBinding>
  <binding name="myBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    <security mode="TransportWithMessageCredential">
      <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
      <message clientCredentialType="UserName" algorithmSuite="Default" />
    </security>
  </binding>
</basicHttpBinding>

我认为基本上我要做的是将 WCF 配置为在请求中使用 UserName 客户端凭据,并在响应中使用证书客户端凭据。不过我不知道该怎么做。

我是 WCF 的新手,所以如果这是一个愚蠢的问题,我很抱歉。我一直在尝试使用 Google 解决方案,但配置 WCF 的方法似乎有很多不同的方式,以至于我不知所措。

提前致谢!

【问题讨论】:

    标签: wcf soap wcf-client


    【解决方案1】:

    对于任何感兴趣的人,我可以通过创建一个 CustomMessageEncoder(在 this MSDN article 的帮助下)在 WCF 能够处理它之前拦截响应消息来解决这个问题。在那里,我从响应中删除了 BinarySecurityToken 和 Signature 元素,然后将其交给 WCF。我使用以下方法从流中删除了有问题的元素:

        private Stream RemoveSignatures(Stream stream)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(stream);
    
            XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
            nsMgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
            nsMgr.AddNamespace("dsig", "http://www.w3.org/2000/09/xmldsig#");
            nsMgr.AddNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    
            XmlNode signatureNode = doc.SelectSingleNode("/soap:Envelope/soap:Header/wsse:Security/dsig:Signature", nsMgr);
            XmlNode binarySecurityTokenNode = doc.SelectSingleNode("/soap:Envelope/soap:Header/wsse:Security/wsse:BinarySecurityToken", nsMgr);
            XmlNode headerNode = doc.SelectSingleNode("/soap:Envelope/soap:Header/wsse:Security", nsMgr);
    
            headerNode.RemoveChild(signatureNode);
            headerNode.RemoveChild(binarySecurityTokenNode);
    
            return new MemoryStream(new UTF8Encoding().GetBytes(doc.OuterXml));
        }
    

    显然这不是最好的解决方案。这非常“hacky”。但它有效,如果需要,我可以继续使用它,因为 HTTPS 传输已经处理了消息安全性。

    如果有人能告诉我一个更好的方法来解决这个问题,我很乐意。

    【讨论】:

      【解决方案2】:

      似乎服务不会在您提供凭据的地方等待凭据。尝试指定传输级别的用户名和密码。

      【讨论】:

      • 该服务以我现在设置的方式接受我在消息中的凭据。我发送请求,WCF 收到正确的响应。问题在于 WCF 未能处理响应中的签名。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-04
      • 2022-08-19
      • 1970-01-01
      • 2015-04-18
      相关资源
      最近更新 更多