views:

736

answers:

1

I'm running a WCF service that, among other things, is used as the back end for a web site. Because both the web site and the WCF service are running on the same machine, and in the interests of performance, I set it up with a netTcpBinding.

Now the thing is, because they exist on the same box, I really don't care about either transport-level security or message-level encryption; the only possible way the messages could be intercepted is if someone gets into the web server itself, and if they do that I've got bigger problems already.

So my question is: when the client and server are already on a trusted subsystem, what configuration can be used to ensure the netTcpBinding is as fast as possible?

Of course the answer might be to use security of "none". But in my particular case I still need to use UserName authentication against a custom database. Can it be configured so that it still uses UserName authentication, but doesn't bother with certificates or securing the data between the endpoints? Or do I perhaps need to implement a custom behaviour with a custom SOAP header to store the username/password, and then I really can set security to "none"?

Server Config

  <netTcpBinding>
    <binding name="Net_Tcp_Binding">
  <security mode="Message">
   <message clientCredentialType="UserName" />
  </security>
    </binding>
  </netTcpBinding>

It uses custom UserName authentication - basically every call authenticates & authorises against a custom database. The service side also uses a certificate to negotiate with its clients, e.g:

<serviceBehaviors>
  <behavior name="MyBehavior">
    <serviceMetadata httpGetEnabled="true" />
    <serviceDebug includeExceptionDetailInFaults="true" />
    <serviceAuthorization principalPermissionMode="Custom">
      <authorizationPolicies>
        <add policyType="MyAssembly.CustomAuthorizationPolicy,MyAssembly" />
      </authorizationPolicies>
    </serviceAuthorization>
    <serviceCredentials>
      <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyAssembly.CustomCredentialValidator,MyAssembly" />
      <serviceCertificate x509FindType="FindBySubjectName" findValue="CN=servercert" storeLocation="LocalMachine" storeName="My" />
    </serviceCredentials>
  </behavior>
</serviceBehaviors>

Client Config

<netTcpBinding>
  <binding name="Net_Tcp_Endpoint">
    <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
    <security mode="Message">
      <message clientCredentialType="UserName" />
    </security>
  </binding>
</netTcpBinding>
+4  A: 

"None" would be fastest, yes :-)

On the other hand, if your service and backend are running on the same machine, you should also have a serious look at the netNamedPipe binding, which is the absolute optimum if you have "on machine" communication. It's even faster and more efficient than netTcp.

In order to authenticate the caller against the service, you would need to use some method of security - since netNamedPipe only support "none" or "Windows", I'd pick Windows. If you use none, you have no way of identifying (authenticating) the caller, and thus, you cannot have authorization (who can do what) based on the caller's identity.

Once you've authenticated the caller (who is calling me), then you can use either Windows groups or the built-in ASP.NET membership/role-provider subsystem to do role-based authorization, in order to make sure who can do what operations. This can be configured using a service behavior called <serviceAuthoritzation> in your behavior section of the service's config.

Marc

marc_s