C# 使用 net tcp 的 WCF 双工服务:“需要流安全性...”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/864917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 04:44:24  来源:igfitidea点击:

WCF duplex service using net tcp: "Stream Security is required..."

c#wcfweb-servicesduplex

提问by Gromer

I'm writing a service that allows users to register with it and receive notifications when an event happens. I'm trying to do this with netTcpBinding, but keep coming up with errors, even when running on my local machine.

我正在编写一个服务,允许用户注册并在事件发生时接收通知。我正在尝试使用 netTcpBinding 执行此操作,但是即使在我的本地计算机上运行时也会不断出现错误。

When I try to send a notification, I am timing out, getting this error:

当我尝试发送通知时,我超时,收到此错误:

Stream Security is required at http://www.w3.org/2005/08/addressing/anonymous, but no security context was negotiated. This is likely caused by the remote endpoint missing a StreamSecurityBindingElement from its binding.

http://www.w3.org/2005/08/addressing/anonymous需要流安全,但没有协商安全上下文。这可能是由于远程端点在其绑定中缺少 StreamSecurityBindingElement 造成的。

For testing I am hosting the service in a console, and it is opening for me and I can see the WSDL and run svcutil on it. When I run the client though, and try to send a notification is when the error above shows up.

为了测试,我将服务托管在控制台中,它正在为我打开,我可以看到 WSDL 并在其上运行 svcutil。但是,当我运行客户端并尝试发送通知时,就会出现上述错误。

Host App.config:

主机 App.config:

<system.serviceModel>
<services>
  <service name="CompanyName.WebServices.InterventionService.RegistrationService"
           behaviorConfiguration="RegistrationServiceBehavior">
    <endpoint address="http://localhost:8000/CompanyName/Registration"
              binding="wsDualHttpBinding"
              contract="CompanyName.WebServices.InterventionService.Interfaces.IRegistrationService"/>
    <endpoint address="net.tcp://localhost:8001/CompanyName/Registration"
              binding="netTcpBinding"
              contract="CompanyName.WebServices.InterventionService.Interfaces.IRegistrationService"/>
  </service>
  <service name="CompanyName.WebServices.InterventionService.NotificationService"
           behaviorConfiguration="NotificationServiceBehavior">
    <endpoint address="http://localhost:8010/CompanyName/Notification"
              binding="wsDualHttpBinding"
              contract="CompanyName.WebServices.InterventionService.Interfaces.INotificationService"/>
    <endpoint address="net.tcp://localhost:8011/CompanyName/Notification"
              binding="netTcpBinding"
              contract="CompanyName.WebServices.InterventionService.Interfaces.INotificationService"/>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="RegistrationServiceBehavior">
      <serviceMetadata httpGetEnabled="true"
                       httpGetUrl="http://localhost:8000/CompanyName/Registration"/>
    </behavior>
    <behavior name="NotificationServiceBehavior">
      <serviceMetadata httpGetEnabled="true"
                       httpGetUrl="http://localhost:8010/CompanyName/Notification"/>
    </behavior>
    <behavior name="netTcpRegistrationServiceBehavior">
      <serviceMetadata httpGetEnabled="true"
                       httpGetUrl="net.tcp://localhost:8001/CompanyName/Registration"/>
    </behavior>
    <behavior name="netTcpNotificationServiceBehavior">
      <serviceMetadata httpGetEnabled="true"
                       httpGetUrl="net.tcp://localhost:8011/CompanyName/Notification"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

Here is the client App.config:

这是客户端 App.config:

<system.serviceModel>
<bindings>
  <netTcpBinding>
    <binding name="NetTcpBinding_IRegistrationService">
      <security mode="None">
        <message clientCredentialType="None"/>
        <transport clientCredentialType="None"/>
      </security>
    </binding>
    <binding name="NetTcpBinding_INotificationService">
      <security mode="None">
        <message clientCredentialType="None"/>
        <transport clientCredentialType="None"/>
      </security>
    </binding>
  </netTcpBinding>
  <wsDualHttpBinding>
    <binding name="WSDualHttpBinding_IRegistrationService">
      <reliableSession ordered="true"/>
      <security mode="None">
        <message clientCredentialType="None" negotiateServiceCredential="false"/>
      </security>
    </binding>
    <binding name="WSDualHttpBinding_INotificationService">
      <reliableSession ordered="true"/>
      <security mode="None">
        <message clientCredentialType="None" negotiateServiceCredential="false"/>
      </security>
    </binding>
  </wsDualHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost:8000/GPS/Registration"
            binding="wsDualHttpBinding"
            bindingConfiguration="WSDualHttpBinding_IRegistrationService"
            contract="IRegistrationService"
            name="WSDualHttpBinding_IRegistrationService">
  </endpoint>
  <endpoint address="net.tcp://localhost:8001/GPS/Registration"
            binding="netTcpBinding"
            bindingConfiguration="NetTcpBinding_IRegistrationService"
            contract="IRegistrationService"
            name="NetTcpBinding_IRegistrationService">
  </endpoint>
  <endpoint address="http://localhost:8010/GPS/Notification"
            binding="wsDualHttpBinding"
            bindingConfiguration="WSDualHttpBinding_INotificationService"
            contract="INotificationService"
            name="WSDualHttpBinding_INotificationService">
  </endpoint>
  <endpoint address="net.tcp://localhost:8011/GPS/Notification"
            binding="netTcpBinding"
            bindingConfiguration="NetTcpBinding_INotificationService"
            contract="INotificationService"
            name="NetTcpBinding_INotificationService">
  </endpoint>
</client>

I've omitted a lot of the registration code since I am only trying to get the notification working right now.

我省略了很多注册码,因为我现在只是想让通知正常工作。

The plan is to host this in a windows service in 2003 Server that is not part of the customer's domain (their setup), and the client computers will be on the customer's domain.

计划是将其托管在 2003 Server 中的 Windows 服务中,该服务不属于客户的域(他们的设置),并且客户端计算机将位于客户的域中。

Edit:

编辑:

I have added the bindings to the host's App.config:

我已将绑定添加到主机的 App.config:

<bindings>
  <netTcpBinding>
    <binding name="NetTcpBinding_IRegistrationService">
      <security mode="None">
        <message clientCredentialType="None"/>
        <transport clientCredentialType="None"/>
      </security>
    </binding>
    <binding name="NetTcpBinding_INotificationService">
      <security mode="None">
        <message clientCredentialType="None"/>
        <transport clientCredentialType="None"/>
      </security>
    </binding>
  </netTcpBinding>
  <wsDualHttpBinding>
    <binding name="WSDualHttpBinding_IRegistrationService">
      <reliableSession ordered="true"/>
      <security mode="None">
        <message clientCredentialType="None" negotiateServiceCredential="false"/>
      </security>
    </binding>
    <binding name="WSDualHttpBinding_INotificationService">
      <reliableSession ordered="true"/>
      <security mode="None">
        <message clientCredentialType="None" negotiateServiceCredential="false"/>
      </security>
    </binding>
  </wsDualHttpBinding>
</bindings>

This still errors, with the same Steam Security is required error message. Trying a small subset of this app in a new solution.

这仍然是错误的,同样的 Steam Security is required 错误信息。在新解决方案中尝试此应用程序的一小部分。

采纳答案by marc_s

Well, your problem appears to be this:

好吧,你的问题似乎是这样的:

  • on the server side, you use a default netTCP binding with no parameters - you don't change anything on it. netTCP defaults to transport-level security with Windows credentials

  • on your client however, you explicitly turn OFF any security on the netTCP binding

  • 在服务器端,您使用没有参数的默认 netTCP 绑定 - 您不会对其进行任何更改。netTCP 默认使用 Windows 凭据进行传输级安全

  • 但是,在您的客户端上,您明确关闭了 netTCP 绑定上的任何安全性

So the two don't match and don't agree on what to do.

所以两者不匹配,也不同意做什么。

Either you need to turn OFF all security on BOTH ends - server AND client - or you need to just use the secure defaults (with Windows credentials).

您要么需要关闭两端(服务器和客户端)上的所有安全性,要么只需要使用安全默认值(使用 Windows 凭据)。

Marc

马克

回答by Howard Hoffman

I think it turns out this is one of those horrible error messages that leads you into many different directions. The above answers is correct for that case. My case was different - my security settings were identical on client and serve.

我认为事实证明这是将您引向许多不同方向的可怕错误消息之一。对于这种情况,上述答案是正确的。我的情况不同 - 我的安全设置在客户端和服务器上是相同的。

In my case, this link pointed out my particular flaw: http://www.netframeworkdevs.com/windows-communication-foundation-wcf/error-invoking-service-with-a-net-tcp-binding-123918.shtml.

就我而言,此链接指出了我的特殊缺陷:http: //www.netframeworkdevs.com/windows-communication-foundation-wcf/error-invoking-service-with-a-net-tcp-binding-123918.shtml

My service-side app.config for the Endpoint had bindingNameas the attribute to name the binding configuration ... instead of bindingConfiguration. I don't think there even is an attribute named bindingNameon an endpoint.

我的端点的服务端 app.configbindingName作为属性来命名绑定配置 ... 而不是bindingConfiguration. 我不认为甚至有一个名为属性bindingNameendpoint

So ... my take away is that this error means "there is a WCF configuration error" perhaps narrowed to the service-side configuration. Ugh.

所以......我的结论是,这个错误意味着“存在 WCF 配置错误”可能缩小到服务端配置。啊。