views:

260

answers:

1

I've got a WCF service that will need to receive client credentials, and maintain some kind of role-based data, based on my auth method.

The clients will reside on many different systems, and as such, each client will have a unique userID and pw.

I'm using basicHttpBinding and have read a few articles, such as this one, http://nirajrules.wordpress.com/2009/05/22/username-over-https-custombinding-with-wcf%E2%80%99s-channelfactory-interface/, that describe the process.

So what I'm looking for is if someone has a full client/server configured like this to take a look at so I can derive my own solution from this.

What I'd like to do is have the username and password passed in the headers for each request, passing back some kind of SecurityTokenValidationException on fail, or continuing if passing.

Thanks.

UPDATE

I'm using the wsHttpbinding with the following config on both the client and server:

  <wsHttpBinding>
    <binding name="wsHttpEndpointBinding" >
      <security mode="TransportWithMessageCredential">
        <transport clientCredentialType="Basic" />
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </wsHttpBinding>

And the call out to the server from the client as follows:

ServiceReference1.ServiceClient myClient = new ServiceReference1.ServiceClient();

myClient.ClientCredentials.UserName.UserName = "billuser";
myClient.ClientCredentials.UserName.Password = "mypassword";

Response.Write("Data from WCF Service: " + myClient.GetData(1));

I think I need a bit of a hand with linking up the CustomUsernamePasswordValidator on the server as I'm still getting the '...could not be activated.' error.

+1  A: 

Are you required to use the basicHttpBinding? That binding is really only there to provide support for legacy WS-BasicProfile implementations (i.e. ASMX). If your clients are also .NET/WCF, I would highly recommend using wsHttpBinding, which provides a plethora of security options out of the box. You could use certificates, username/password, etc. with transport and/or message security and not need to write any of the security stuff yourself. Just configure-and-go (CAG).

Security credential information is available to the service itself via the OperationContext, in case you need to access it directly from your code. If your code does need to access it, however, I would recommend writing a behavior to extract the pertinent information from the OperationContext and place it in something more application specific so that you don't have to reference System.ServiceModel everywhere you need to access information on OperationContext.

jrista
When I switched from basicHttpbinding to wsHttpbinding (endpoint binding="wsHttpBinding" bindingConfiguration="wsHttp") I'm getting the error, "The requested service ... could not be activated. See the server's diagnostic trace logs for more information." As this is a hosted solution, I don't have access to the log.I'm doing this over https.
ElHaix
If you are using https, did you configure transport security for the binding? Transport security means the transport protocol encrypts the channel. Since you are using https, you would need to enable transport security for the binding. Try configuring that and see if it works. You will probably need to be able to see the full exception report to get security working. It is usually a little bit of trial and error to get it up and running...its not really "difficult", just not "obvious" the first time you implement security for an endpoint.
jrista
For the wsHttpbinding for both client and server, I set security mode="TransportWithMessageCredential", transport clientCredentialType="Basic", message clientCredentialType="UserName". So by the error message, I know they're talking to each other, just not properly :). I also set proxy.ClientCredentials.UserName.UserName and proxy.ClientCredentials.UserName.Password before making the service call (if I didn't, that's another error).
ElHaix
oh, and yes, I'm still experiencing the '...could not be activated' error - even though I've got the bindings setup the same on both client/server.
ElHaix
If you can find any way to capture and log the exception to your own file or database record some how, having that additional stack trace information will be a huge help in figuring out what the problem is now. You should be on the right track now, though, with wsHttpBinding. Security can sometimes be tedious initially, but once it is set up, you don't have to worry about it.
jrista
jrista: that really helped actually. I setup service logging, and since this is a hosted solution and the host techs are pretty solid, they looked up the logged errors for me. This is up and working fine now - WCF over HTTPS with custom client authentication off my own data store and multiple host header handling , thanks to all!
ElHaix
Glad you got it working. :)
jrista