首页 > 解决方案 > WCF 故障代码必须理解 = 1 .net 4.0

问题描述

如何更改我的 wcf 服务以接受 mustunderstand = 1?在这种情况下,我必须更改服务才能接受来自客户端的请求。客户端在标头中发送 mustunderstand =1。

服务配置为使用 basichttpBinding

 <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName"/>
            <transport clientCredentialType="None"></transport>
          </security>

使用soap UI,我将以下用户名令牌插入到标题中

 <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-2684C13EA73A35131015516775308851">
            <wsse:Username>username</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>

         </wsse:UsernameToken>
      </wsse:Security>

当我在 wcf 服务请求中插入此令牌时,我可以在soap UI 上重现该问题。这是错误

<FaultMsgRec>
  <ErrCode>100</ErrCode>
  <ErrCat>Error</ErrCat>
  <ErrDesc>An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.--&gt; The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood by the recipient of this message, causing the message to not be processed.  This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process.  Please ensure that the configuration of the client's binding is consistent with the service's binding. </ErrDesc>
</FaultMsgRec>

由于我可以控制 wcf 服务,因此我可以在服务行为中添加 ValidateMustUnderstand = false。就像链接中解释的那样 https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.description.mustunderstandbehavior.validatemustunderstand?view=netframework-4.7.2

一旦我将此添加到服务行为中,错误就会消失。但我不想关闭标头上的验证,特别是如果它是用户名、密码。我应该怎么做才能允许 mustunderstand=1?我是否遗漏了默认情况下服务不会自动处理 mustunderstand=1 的内容。我知道要在客户端上编写代码以便在标头中发送 0。

我在我的 wcf 服务中使用消息合同而不是数据合同。我了解对于某些属性,我可以添加类似此链接的属性 https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.messageheaderattribute.mustunderstand?view=netframework-4.7.2。但我没有添加任何属性。我只是将它添加到 soapenv:mustunderstand=1 的第一个链接中

请帮忙!。

谢谢

标签: wcf

解决方案


不确定这是否可以解决您的问题。但是您可以尝试在 web.config 中添加您的标头。

  <endpoint address="http://ws-wuxipc-5077:4000/calculator" binding="basicHttpBinding"
  contract="ServiceInterface.ICalculatorService" name="cal">
  <headers>
    <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" >
      <wsse:UsernameToken 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:Username>
        </wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">monMonDePasse</wsse:Password>
        <wsse:Nonce>sdsdsdlojhfdsdM5Nw==</wsse:Nonce>
        <wsu:Created>2019-01-21T6:17:34Z</wsu:Created>
      </wsse:UsernameToken>
    </Security>
  </headers>
</endpoint>

或者您可以使用代码添加标题。

 using (ChannelFactory<ICalculatorService> ChannelFactory = new ChannelFactory<ICalculatorService>("cal"))
    {
                        ICalculatorService employeeService = ChannelFactory.CreateChannel();
        using (OperationContextScope scope = new OperationContextScope((IContextChannel)employeeService))
        {

            System.Xml.XmlDocument document = new XmlDocument();


            XmlElement element = document.CreateElement("wsse", "UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");


            XmlElement newChild = null;

            newChild = document.CreateElement("wsse", "Username", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            newChild.InnerText = "finance";
            element.AppendChild(newChild);

            newChild = document.CreateElement("wsse", "password", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            newChild.SetAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
            newChild.InnerText = "387";
            element.AppendChild(newChild);

            MessageHeader messageHeader = MessageHeader.CreateHeader("security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", element, false); // here is mustunderstood is set to false


            OperationContext.Current.OutgoingMessageHeaders.Add(messageHeader);

        }

                       Console.Read();
    }

推荐阅读