views:

408

answers:

1

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.

A: 

I think you need to use the 'bindingConfiguration' attribute to specify which binding configuration to utilize for each service endpoint.

MattK
Thanks but I had tried that already and it results in an exception being thrown, stating that I cannot define more than one `netTcpBinding` node under `bindings`. This happens for both the server and the client configuration files.
Sandor Drieënhuizen
My initial response was incorrect...I have edited it to what I think may be your issue...
MattK
You're right, I inadvertently omitted the `bindingConfiguration` attributes; they are in my test project though. I'm using .NET 4.0 by the way, which supports default binding configurations (which is a great thing in terms of simplification). If no `bindingConfiguration` is specified, the binding configuration that has no `name` attribute is implied. This is way I omitted the `bindingConfiguration` attributes on 'Service1'.
Sandor Drieënhuizen
I'm still out of luck on this...
Sandor Drieënhuizen