CustomHTTPBinding相当于BasicHTTPBinding和enableUnsecuredResponse

时间:2017-01-22 13:33:49

标签: c# wcf

我想使用WCF连接到服务Web服务,该服务使用证书进行身份验证是消息级别。

我目前在App.config中有这个配置:

<basicHttpBinding>
    <binding name="SomeServiceHttpsBinding">
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
      <security mode="TransportWithMessageCredential">
        <transport clientCredentialType="None" />
        <message clientCredentialType="Certificate" />
      </security>
    </binding>
</basicHttpBinding>

,此绑定在服务的端点中指定。

连接正常,服务器发送,接受并响应请求,但服务器的响应中不包含任何安全标头(我使用代理调试器检查了实际响应)。所以我得到了这个例外:

  

未处理的类型异常   发生'System.ServiceModel.Security.MessageSecurityException'   mscorlib.dll中

     

其他信息:安全处理器无法找到   消息中的安全标头。这可能是因为消息是   一个不安全的错误或因为它之间存在绑定不匹配   沟通各方。如果配置了服务,则会发生这种情况   为了安全起见,客户端没有使用安全性。

我发现我必须将绑定类型从<basicHttpBinding>更改为<customBinding>,并将属性enableUnsecuredResponse="true"添加到其中以解决此问题。但它有很多复杂的选项让我困惑,我不知道我怎么能在这里做同样的事情。

现在问题是,如何以<customBinding>格式编写上述设置的等效内容,以便我也可以使用enableUnsecuredResponse

2 个答案:

答案 0 :(得分:1)

这是我解决问题的方法。希望这也有助于其他人。

  <customBinding>
    <binding name="SthHttpsBinding">
      <security enableUnsecuredResponse="true" authenticationMode="CertificateOverTransport">
      </security>
      <httpsTransport maxBufferSize="1048576"
          maxReceivedMessageSize="1048576" maxBufferPoolSize="10485760"></httpsTransport>
    </binding>
  </customBinding>

答案 1 :(得分:0)

我找到了解决我几乎类似问题的另一种方法(由代码完成,而不是通过配置和BasicHttpsBinding)。这是一个基于带有用户名/密码的SOAP消息的解决方案(为了使样本易于测试)

    private static ChannelFactory<T> CreateSecureChannel<T>(string url, string username, string password)
    {
        var binding = new BasicHttpsBinding
        {
            MessageEncoding = WSMessageEncoding.Text,
            UseDefaultWebProxy = true,
            BypassProxyOnLocal = false,
            Security =
            {
                Mode = BasicHttpsSecurityMode.TransportWithMessageCredential,
                Transport =
                {
                    ClientCredentialType = HttpClientCredentialType.None,
                    ProxyCredentialType = HttpProxyCredentialType.None
                },
                Message =
                {
                    ClientCredentialType = BasicHttpMessageCredentialType.UserName,
                    AlgorithmSuite = SecurityAlgorithmSuite.Default
                }
            }
        };

        var channel = new ChannelFactory<T>(binding, new EndpointAddress(url));

        var elements = binding.CreateBindingElements();
        elements.Find<SecurityBindingElement>().EnableUnsecuredResponse = true;
        var customBinding = new CustomBinding(binding);
        customBinding.Elements.Clear();
        customBinding.Elements.AddRange(elements.ToArray());
        channel.Endpoint.Binding = customBinding;

        channel.Credentials.UserName.UserName = username;  
        channel.Credentials.UserName.Password = password;
        return channel;
    }