如何为单个方案配置多个WCF绑定配置
我有一组 IIS7 托管的 net.tcp WCF 服务,为我的 ASP.NET MVC Web 应用程序提供服务。 Web 应用程序可通过 Internet 访问。
WCF 服务 (IIS7) <--> ASP.NET MVC 应用程序<-->客户端浏览器
服务经过用户名身份验证,客户端(我的 Web 应用程序)用于登录的帐户最终成为主机上的当前主体。
我希望对其中一项服务进行不同的身份验证,因为它为我的登录视图提供视图模型。当它被调用时,客户端显然还没有登录。我认为,如果服务托管在与 Web 应用程序不在同一域中的计算机上,Windows 身份验证可以提供最好的服务,或者可能只是基于证书的安全性(事实上,我也应该将其用于经过身份验证的服务)。
但这不是重点。使用多个 TCP 绑定给我带来了麻烦。我尝试在客户端配置中这样设置:
<bindings>
<netTcpBinding>
<binding>
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
<binding name="public">
<security mode="Transport">
<message clientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint contract="Server.IService1" binding="netTcpBinding" address="net.tcp://localhost:8081/Service1.svc"/>
<endpoint contract="Server.IService2" binding="netTcpBinding" bindingConfiguration="public" address="net.tcp://localhost:8081/Service2.svc"/>
</client>
服务器配置是这样的:
<bindings>
<netTcpBinding>
<binding portSharingEnabled="true">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
<binding name="public">
<security mode="Transport">
<message clientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Service1">
<endpoint contract="Server.IService1, Library" binding="netTcpBinding" address=""/>
</service>
<service name="Service2">
<endpoint contract="Server.IService2, Library" binding="netTcpBinding" bindingConfiguration="public" address=""/>
</service>
</services>
<serviceHostingEnvironment>
<serviceActivations>
<add relativeAddress="Service1.svc" service="Server.Service1"/>
<add relativeAddress="Service2.svc" service="Server.Service2"/>
</serviceActivations>
</serviceHostingEnvironment>
问题是这两个绑定似乎不想在我的主机中一起生活。当我删除其中任何一个时,一切都很好,但它们一起在客户端上产生以下异常:
“net.tcp://localhost:8081/Service2.svc”不支持请求的升级。这可能是由于绑定不匹配造成的(例如,在客户端启用安全性,而不是在服务器启用安全性)。
在服务器跟踪日志中,我发现以下异常:
协议类型 application/negotiate was sent to a不支持该类型升级的服务。
我是否在寻找正确的方向或者是否有更好的方法来解决这个问题?
更新
虽然这个问题似乎相当老了,但它仍然与我相关(我认为也与其他人相关)。目前,在访问最初不应进行身份验证的服务时,我正在使用神奇的用户名/密码组合(因为当前主体需要用户名)。鉴于这个问题,您可以看到我宁愿有一个专门针对这些公共服务的未经身份验证的绑定。在这种情况下,神奇帐户并不是不安全的,它不提供除公共级别之外的任何访问权限。
I have a set of IIS7-hosted net.tcp WCF services that serve my ASP.NET MVC web application. The web application is accessed over the internet.
WCF Services (IIS7) <--> ASP.NET MVC Application <--> Client Browser
The services are username authenticated, the account that a client (of my web application) uses to logon ends up as the current principal on the host.
I want one of the services to be authenticated differently, because it serves the view model for my logon view. When it's called, the client is obviously not logged on yet. I figure Windows authentication serves best or perhaps just certificate based security (which in fact I should use for the authenticated services as well) if the services are hosted on a machine that is not in the same domain as the web application.
That's not the point here though. Using multiple TCP bindings is what's giving me trouble. I tried setting it up like this in my client configuration:
<bindings>
<netTcpBinding>
<binding>
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
<binding name="public">
<security mode="Transport">
<message clientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint contract="Server.IService1" binding="netTcpBinding" address="net.tcp://localhost:8081/Service1.svc"/>
<endpoint contract="Server.IService2" binding="netTcpBinding" bindingConfiguration="public" address="net.tcp://localhost:8081/Service2.svc"/>
</client>
The server configuration is this:
<bindings>
<netTcpBinding>
<binding portSharingEnabled="true">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
<binding name="public">
<security mode="Transport">
<message clientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Service1">
<endpoint contract="Server.IService1, Library" binding="netTcpBinding" address=""/>
</service>
<service name="Service2">
<endpoint contract="Server.IService2, Library" binding="netTcpBinding" bindingConfiguration="public" address=""/>
</service>
</services>
<serviceHostingEnvironment>
<serviceActivations>
<add relativeAddress="Service1.svc" service="Server.Service1"/>
<add relativeAddress="Service2.svc" service="Server.Service2"/>
</serviceActivations>
</serviceHostingEnvironment>
The thing is that both bindings don't seem to want live together in my host. When I remove either of them, all's fine but together they produce the following exception on the client:
The requested upgrade is not supported by 'net.tcp://localhost:8081/Service2.svc'. This could be due to mismatched bindings (for example security enabled on the client and not on the server).
In the server trace log, I find the following exception:
Protocol Type application/negotiate was sent to a service that does not support that type of upgrade.
Am I looking into the right direction or is there a better way to solve this?
UPDATE
Although this question seems to be fairly old, it's still relevant to me (and I think to others as well). Currently, I am using a magical username/password combination (because the current principal needs a username) when accessing services that shouldn't be authenticated in the first place. In light of this question, you can see that I'd rather have an unauthenticated binding specifically for those public services. In this case, a magical account is not insecure, it doesn't provide any access other than on the public level.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试使服务能够使用多个绑定:
Try to enable the service to use multiple bindings:
我认为您需要使用“bindingConfiguration”属性来指定每个服务端点使用哪个绑定配置。
I think you need to use the 'bindingConfiguration' attribute to specify which binding configuration to utilize for each service endpoint.