views:

1431

answers:

2

Am I correct in understanding that a WCF Service could be setup with "Transport Security", + "Certificate Authentication" and without a "Client Certificate" installed client side?

My scenario would be:

  • WCF Services on Remote Server
  • Windows Forms Client shipped potentially to hundreds of users (authenticates users (against DB) and performs actions over WCF service methods)

I want my messages encrypted over SSL, that is why I have selected the "Transport" method and I believe why I also need the server certificate.

I have followed a walkthrough which gave me all of the above but included necessity of having a client certificate installed? If I am shipping this windows forms app to clients, how could they install the certificate if I was forced to require this? It really seems like I'm missing a big point here as I would think installing a certificate to a users machine would be quite a big ask.

PS. Potentially from what I am reading here, am I over-complicating my task at hand? Do I just need an SSL certificate installed into our web server and simply access the WCF service via HTTPS and possibly be able to just use basicHttpBinding? Effectively not needing to worry about 'certificate authentication' mechanisms?

+1  A: 

You don't need a client certificate, it's simply ssl. If you're using IIS to host the service, this is a no brainer, just install the cert. Message level security get's a little bit more tricky but you should be okay on the ssl cert.

If you use basicHttpBinding you won't need to shutoff authentication, by default WSHttpBinding turns on message level authentication, which you can shut off in the web config by setting Authentication mode (I believe) to none. Go with basic if you just need ssl. If you want ssl and perhaps Windows Authentication, then go with WSHttpBinding.

Joshua Belden
Ok thanks. I really thought I over-complicated it. WCF lures you down the track of stating if you want to secure your service, adopt wsHttpBinding. Grrrr-argh.
GONeale
@Josh OK, I am trying to get basicHttpBinding going just without SSL enabled for now (need to get cert registered). Does this code look right however for if the service was hit over HTTPS with an SSL cert? http://pastebin.com/m6ca08ad6
GONeale
That looks fine. You can actually reuse your behaviors like you did with the binding configuration. Are you getting any errors?You may need to add this to the binding's security configuration, <transport clientCredentialType="None"/>, to shutoff any client requirements.
Joshua Belden
Ok true Josh, I'll point to the single behavior. Thnx. Yep I think I got it going with clientCredentialType=None to enable it to work without SSL. But glad that looks good for standard SSL.
GONeale
+1  A: 

Hi,

As Joshua said you don't need a client cert if you're going to use username to authenticate your client. In this scenario, the client passes username and password and the server provides the certificate for mutual authentication / handshake process.

I've just recently setup a wcf security system for a similar system (win forms over www) and I used the guidance from CodePlex, which provided a step by step check list to help ensure you have everything in place. You don't have to follow every step, for example we aren't using the Roles functionality, but we are using the Membership store.

Below is a brief summary of the setup/configuration with wsHttpBinding using username and server cert:

Client Config:

      <security mode="Message">
        <message clientCredentialType="UserName" negotiateServiceCredential="true"
          algorithmSuite="Default" establishSecurityContext="false" />
      </security>

Username Password set on proxy:

'ClientCredentials added to service call for authentication
    objServiceClient.ClientCredentials.UserName.UserName = MyAppContext.Username
    objServiceClient.ClientCredentials.UserName.Password = MyAppContext.Password

Server Config:

  • Binding:

      <wsHttpBinding>
      <binding name="MyApp.wsHttpBindingMessageUname">
       <security mode="Message">
        <message clientCredentialType="UserName" negotiateServiceCredential="true"
          establishSecurityContext="false" />
       </security>
      </binding>
      </wsHttpBinding>
    
  • Behaviour:

      <serviceBehaviors>
      <behavior name="MyApp.DefaultServiceBehavior">
       <serviceCredentials>
        <serviceCertificate findValue="localhost" storeLocation="LocalMachine"
         storeName="My" x509FindType="FindBySubjectName" />
        <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
         membershipProviderName="AspNetSqlMembershipProvider" />
       </serviceCredentials>
      </behavior>
     </serviceBehaviors>
    

Hope that's of some help, if you have any questions let me know.

Tanner
Thanks. What username/password is that? A username/password set on the server as windows authentication? Or custom username/password you accept on your form checked against a db?
GONeale
In our scenario, we used aspnet membership so within our server config we have a < membership > block which defines the membership provider, connection string for the db, amongst other settings. This lets WCF know where to validate the credentials against.
Tanner