views:

1194

answers:

2

I have a WCF service deployed on another machine and I want to authenticate the client against the WCF service.

I have done the following things :

1) In IIS I have unchecked the Anonymous access and checked the "Integrated Windows Authenfication" check box.

2) My Web config

 <authentication mode="Windows" />
 <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBind">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

3) On the client side I am passing the user credential as below :

MyServiceClient _client;

_client = new MyServiceClient();

_client.ClientCredentials.Windows.ClientCredential.UserName = "username";
_client.ClientCredentials.Windows.ClientCredential.Password = "password";
_client.ClientCredentials.Windows.ClientCredential.Domain = "mydomain";

My Question is how can trap the user name and password on the server side )where the service is deployed) ?

How can I authenticate user against the credential passed ?

Currently I am using basichttp binding .. is this binding good enough to support security model?

Please Help!!

A: 

It looks like you need a custom user name and password validator. There is an MSDN article that covers all the steps: How to: Use a Custom User Name and Password Validator.

BasicHttpBinding supports a variety of security modes. If you use the overloaded constructor, you can pass in the value of your choice for the BasicHttpSecurityMode.

bobbymcr
Thanks for your response. Actually , I have to authenticate user , if it exist in the domain or not.. Like for example my domain is "abcd"My user is "user1" I have to identify the place in Service where I can trap the user1 and check if it exist in the domain or not..
Ashish Ashu
Alright, if you are using straight Windows authentication, then marc_s's answer above is the way to go.
bobbymcr
+3  A: 

On the server side, you can either authenticate against Active Directory using Windows credentials being passed in, or then you'll need to use an alternate store to handle user authentication.

You can access the caller's identity in your server side code using:

IIdentity caller = ServiceSecurityContext.Current.PrimaryIdentity;

You can also check whether a Windows user called with its Windows credentials (as in your sample) by checking the

ServiceSecurityContext.Current.WindowsIdentity

If it's NULL, then no Windows credentials have been passed - otherwise you can use this Windows identity to check who is calling (name etc.) - you won't be able to read the user's password, though! You can check his name, what groups he belongs to, and more.

To use Windows/Active Directory validation, set the clientCredentialType to "Windows". You might have to switch to wsHttpBinding, or even better: netTcpBinding (if you're on a Windows LAN behind a firewall).

<bindings>
  <netTcpBinding>
    <binding name="WindowsSecured">
      <security mode="Transport">
        <transport clientCredentialType="Windows" />
      </security>
    </binding>
  </netTcpBinding>
</bindings>

With this, only users who are registered in your Windows domain can even call the service. Any other users will be refused without any additional work on your side.

Once you have the Windows user calling, you can check out the ServiceSecurityContext.Current.WindowsIdentity for information about who's calling.

Check the MSDN docs for details on what's available on the service security context, or the Windows identity.

Marc

marc_s
Hi Marc,Thanks for your response.I want security model which requires users to have accounts in a Windows domain.
Ashish Ashu
The current sample requires using a SQL Server database to store the user information but i don't want that, I want to validate user against active directory .. If it exist in current domain or not. If the user exist then in which groups .. etc
Ashish Ashu
updated to show how to use AD authorization
marc_s
Thanks again marc,I want to clear one more thing , if this code will work in my scenario.Acutally my "wcf service " is deployed in several machines accross the world and all the machines is in same domain. Is this code will work in that scenario.Acutally I have to validate user if it belongs to same domain or not.Also when I am using net tcp binding I am getting the following error when I add the service reference .Could not find a base address that matches scheme net.tcp for the endpoint with binding NetTcpBinding. Registered base address schemes are [http].
Ashish Ashu
Also when I user wsHttpBinding I am getting the follwoing error:The service certificate is not provided. Specify a service certificate in ServiceCredentials.
Ashish Ashu
For the netTCP: you either have to add an entry to your "baseAddresses" in your service's `<host>` section: `<add baseAddress="net.tcp://YourServer:7575/YourServiceName" />` or you need to specify a FULL address with the "net.tcp" prefix in your service endpoint.
marc_s
The AD check will work, if all servers and their users are on the SAME domain, or in domain that are in a mutual TRUST relationship.
marc_s
Thanks again Marc,I am wondering where can I put my code to authenticate user in wcf service. Yes , you have already told that how can take user name .Thanks for your patience..
Ashish Ashu
You don't have to do anything - WCF takes care of authentication. If the user is *NOT* authenticated, he won't be able to call your method and will get an exception. You can get tne name of the caller frmo the WindowsIdentity.Name property.
marc_s
Marc can you please provide the name of exception, so that I can handle that exception.Many thanks for your help
Ashish Ashu