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.