1

我已经使用这种绑定配置创建了服务:

<bindings>
  <customBinding>
    <binding name="DefaultBinding">
      <textMessageEncoding messageVersion="Soap12" />
      <httpTransport />
    </binding>
  </customBinding>
</bindings>

当我的服务收到这样的消息时:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <UsernameToken>
        <Username>
        </Username>
        <Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">...</Password>
        <Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">KWVa4abCrEemOMT55VEZkgIAAAAAAA==</Nonce>
        <Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2013-08-28T13:29:05.966Z</Created>
      </UsernameToken>
    </Security>
    ...

它产生错误:

名称空间“ http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd ”中的标题“Security”不被理解......

我也试过:

<wsHttpBinding>
    <binding name="DefaultBinding">
      <security  mode="Message" />
    </binding>
</wsHttpBinding>

我如何处理此标头或忽略它?


更新

据我了解,我需要用户名而不是不安全的传输,所以我尝试了:

<customBinding>
    <binding
        name="DefaultBinding">
      <textMessageEncoding messageVersion="Soap12" />
      <security authenticationMode="UserNameOverTransport" allowInsecureTransport="True">
      </security>
      <httpTransport>

      </httpTransport>
    </binding>
</customBinding>

我也试过CUB

<bindings>
  <clearUsernameBinding>
    <binding name="myClearUsernameBinding" messageVersion="Soap12">
    </binding>
  </clearUsernameBinding>
</bindings>

双方都以客户端错误结束:验证消息安全性时发生错误。但它适用于测试 CUB 的客户端。有什么问题?

CUB 的信封

测试客户端的标头

4

4 回答 4

2

解决方案很简单:

  1. 创建服务行为
  2. 创建调度消息检查器
  3. 将创建的服务行为添加到服务器

然后只需解析或删除未使用的“mustUnderstand”标头。

第1步:

public class WSSecurityBehavior : IServiceBehavior {
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
    }

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
        Collection<ServiceEndpoint> endpoints,
        BindingParameterCollection bindingParameters) {
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
        var endpoints = serviceHostBase
            .ChannelDispatchers
            .Cast<ChannelDispatcher>()
            .SelectMany(dispatcher => dispatcher.Endpoints);

        foreach (var endpoint in endpoints)
            endpoint.DispatchRuntime.MessageInspectors.Add(new WSSecurityInspector());
    }
}

第2步:

public class WSSecurityInspector : IDispatchMessageInspector {
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) {
        var headerPosition = request.Headers.FindHeader("Security",
            "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

        if (headerPosition > -1)
            request.Headers.RemoveAt(headerPosition);

        return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState) {
    }
}

第 3 步:

Host.Description.Behaviors.Add(new WSSecurityBehavior());
于 2013-08-30T05:58:36.203 回答
1

您在客户端和主机之间交换的肥皂结构/合同不匹配。客户端和主机(包括命名空间)之间交换的消息的结构必须完全匹配。如果他们不这样做,您会收到此错误。

您想要做的是让 Fiddler 在您的主机上运行。然后,将 Fiddler 作为中间人代理运行,从您的客户端计算机重新发送请求。当请求/响应完成后,检查 Fiddler 中的消息,特别是请求和响应之间的命名空间和结构差异,您应该会发现问题所在。

于 2013-08-28T14:06:16.250 回答
0

客户端正在尝试使用消息级别的用户/密码对您的服务器进行身份验证。您需要确定这是否是预期行为,在这种情况下,您需要配置您的服务以进行用户名身份验证。这不仅仅是设置绑定的问题,您需要决定如何验证用户身份(例如通过数据库、Windows 凭据等)。一旦你知道你应该能够使用这样的绑定:

        <customBinding>
            <binding name="NewBinding0">
                <textMessageEncoding />
                <security authenticationMode="UserNameOverTransport">
                    <secureConversationBootstrap />
                </security>
                <httpsTransport />
            </binding>
        </customBinding>

我不能确定这是您需要的,因为您没有发布完整的肥皂信封。您可能需要在文本编码元素上设置 messageVersion 属性,或者在没有 SSL 的情况下使用CUB 。然后,您需要配置验证用户名的方式。一个例子是here

于 2013-08-28T17:47:25.887 回答
0

您可以使用 basicHttpBinding,从这篇文章中下载 项目和示例代码以获取 wcf PasswordDigest Auth中的密码摘要这是我对此实现的配置(我为自定义需求编辑了一些代码,但此解决方案工作正常)。

创建绑定:

 <bindings>
  <basicHttpBinding>
    <binding name="securityBinding">
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

在设置行为之后

 <behavior name="securityBehavior">
      <DataMessageTracer/>     
      <serviceCredentials type="WCF.SecurityExtensions.ServiceCredentialsEx, WCF.SecurityExtensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <serviceCertificate findValue="hypori2.zed.pa" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyService.Utils.PassValidator, MyService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      </serviceCredentials>
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
于 2013-09-20T20:31:53.763 回答