How to implement authenticate communication between client and server in WCF? - wcf

I need to implement a model, where only an authorized set of clients can use a WCF server. I thought of something along passing an AUTH structure as a param inside each method call. Is this the best method to implement this kind of security, or is there an easier/better way of doing this?
for example i developed and publish the service like below:
http://MyServer.my.com/MyService[^]
By default any any one who know the URL can consume the service.
How i can set specified Set of client can consume the URL.
Also how can we assure no one can change the data between communication.
For eg: client send request for Balance Enquiry service with reponse 500 Rs but some one tried to change it to 500 Rs.

For authentication you can use basic authentication. If using IIS, Web Service users can be local users that have read permissions over the svc file.
For channel security you can use transport mode (https). You will need a certificate for this, but it can be a self signed created by you.
This example sets server and client:
http://msdn.microsoft.com/en-us/library/ms733775%28v=vs.110%29.aspx

Related

How to get the identity which sends requests to WCF REST service?

I am wondering how to get the identity which sent a request to WCF RESTful service on the server side. I need to check it against Active Directory for existence and specific rights to decide whether to provide some resources in response or reject the request.
The only way to ensure that the identity of the user is sent to your web service is to program it to be sent in the client software. The user ID will definately not appear automatically amongst the request http headers. If you want it, you have to put it there deliberately through code.
Probably the easiest way would be to "turn on" Windows authentication within the host/client software. Here's a link to a CodeProject demo on now to set up and use windows authentication in WCF:
http://www.codeproject.com/Articles/36289/8-steps-to-enable-windows-authentication-on-WCF-Ba
It does not, however, go into the AD authentication side. That will have to be done through code as well.
Best of luck.

WCF Security - Newbie questions -

I've been reading about WCF security for a whole day and can't say I'm comfortable with it.
I've developed some WCF services and deployed them to a test server and can call from a client. Both sides C# / VS 2010. The services are hosted under IIS 6. No option to go more recent at the moment.
So - I've read that I can only use HTTP with IIS 6 - which I believe restricts me to basicHttpBinding or wsHttpBinding as the binding.
I've also read that the XML sent over the wire using wsHttpBinding is encrypted, whereas basicHttpBinding is not.
So it looks like I want to go with wsHttpBinding as I will want some sort of authentication and I suppose user name / password will be passed along with the incoming messages.
First question is - if I use wsHttpBinding do clients have to call using https? And then do I need to worry about certificates etc. on the server?
Second question is - what security options are available to me? Do the callers have to be Windows users on the server, or can I make up my own user name / password and have that part of the service and the service do the validation and have nothing to do with Windows users? If I have to go with Windows users I suppose it's common to set up one user account on the server and have all callers use that?
The basic idea is I need to open this service to selected callers, but don't want just anyone to be able to discover the service and call it. I need to control somehow who calls the service. Is user name / password the standard way of doing this? Could I define a GUID for example which all callers would have to pass?
In answer to your first question. wsHttpBinding does not require HTTPS. You can use HTTP if you set the SecurityMode to Message or None. However, since you are proposing to send a username and password with the service calls you definately shouldn't do that. If you do then anyone will be able to look at the message in transit and read the username and password and your security is totally compromised. I'm afraid you will have to get a certificate and use HTTPS. It's not so bad though and there are lots of resources on the web to help you.
By the way, you can do HTTPS with basicHttpBinding aswell as wsHttpBinding. Also, you should consider using REST for simplicity. WCF has good support for it (webHttpBinding) and better support coming with the Web API.
In answer to your second questions, you do not need the callers to be Windows users on your server and you can use a username and password. This is called Basic Authentication. Again, there is lots about it on the web. Start here.
If you do this you will obviously have to have a database to store usernames and password so you can validate then and grant or denay access to your service. The simplest way to achieve this with WCF is to use one of the default membership providers.

WCF - Which Binding

I have a web service hosted in IIS 7 that is to be called from a WCF client that runs in a different domain.
Currently, the wsHTTP binding has been configured using default settings. When the call is made the service complains that the client couldn't be authenticated (Message : The request for security token could not be satisfied because authentication failed.). I guess this is because it's trying to use windows authentication and the clients ID cannot be validated against the AD server of the service.
What's the best way to get around this? Can the service be configured to run under the ID of a local account? How best to check the call has come from authorised client? I'd rather avoid certificate generation and management if possible. Ideally, I'd authenticate the client by username / password by then have the service operate under it's own local ID - to gain access to resources on the service server.
Any advise gratefully received.
Thanks
Rob.
You can use user name and password but your service should use certificate if you don't want to send user name and password in plain text. Your option is either:
HTTPS with user name and password in message
Message security with user name and password in message
Both requires certificate.
Here's a good tutorial that I used to do just that.
http://www.codeproject.com/KB/WCF/wcf_https_usernameauth.aspx?msg=3527563#xx3527563xx

Easiest method to use a client-generated token for WCF authentication

(I tried searching, but couldn't find any truly helpful links.)
We are implementing a set of WCF services. What I would like to do in these services is have the clients (which will be trusted application servers) be able to pass a token of some sort to the web service to authenticate. I do not want to be required to pass username/password on the initial or subsequent requests (because in some cases the calling application server may not have the password). Windows and Kerberos are not usable in our specific circumstance.
I had thought to just create a simple custom UserNameSecurityTokenAuthenticator class and modify it so that if the password is empty, it takes userName as the string-encoded token value (obviously checking the token itself to verify that it's valid at that point), but if the password is not empty, forwarding on the username/password to a MembershipProvider for checking. Basically I'd like to overload the username/password authentication to provide for token passing as well.
Is this possible? Can I simply plug in a token authenticator like this, or is there some other simple way to "intercept" requests like this (and update the actual username value from the decrypted token)?
Or is there some other incredibly simple way to allow the client to pass a custom token and have the server accept it that I'm just missing?
If it's a fairly controlled environment and not too many clients involved, then I'd try to set up something along the lines of the B2B scenario securing the transport link using certificates on both ends.
Certificates are not bound to Windows or an AD domain, and setting them up is a one-time job.
Read more about that WCF security scenario:
MSDN: Transport Security with Certificate Authentication
Fundamentals of WCF Security: Business Partner Applications
. WCF Security How-To's

Enabling authentication between applications

I have a set of .NET applications running in a public web environment which connect to a centralized component made up of web pages and web services.
Is there any way to implement a security feature to make the centralized web pages be sure of the caller applications identity? Making a post and supplying a querystring parameter stating the caller application is a naive solution, someone can manually change it.
Any ideas? Tks in advance.
Assign secret keys to each client-server pair and use them to sign messages passed between client and server (using HMAC for example).
TLS/SSL/HTTP. You just need to enable client authentication. SSL is usually only used in the scenario where the server needs to be authenticated. But the server end can be configured to authenticate the client also. Digital certs need to be installed on both ends. This then uses all the appropriate crypto to do the job, ie. public authentication, establishment of secure channel, using Diffie-Hellman, RSA, AES/3DES, whatever you configure.
Take a look at this post. Good place to start.
Another option, perhaps have you look at OpenID?
The current situation:
Servers A, B, and C are trusted and controlled by you. A visitor comes to site A and views a page that sends data to site C, and the data contains something like "origin=A". We're concerned that the user will change that to "origin=B".
A simple fix:
You control all three servers, so let them communicate to verify incoming data. For example, A will change "origin=A" to "origin=A&token=12345", where the token value is random. The user tries to tamper with it and sends "origin=B&token=12345" to server C. C makes a trusted connection to B, saying "Did you send someone to me with token 12345?" B says "Nope" and C knows to reject the request.
This can be arbitrarily elaborate, depending on your needs and whether you're using https. Maybe tokens expire after a certain time period. Maybe they're tied to IP address. The point is that server C verifies any information that comes from the end user with servers A and B.
Are you asking about single-sign-on? (i.e. someone authenticated on AppA should also be able to use AppB and AppC without re-authenticating)
You can do this by configuring the machineKey for your apps so they can share asp.net authentication tokens.
The company I work for currently uses shared forms authentication cookies across the enterprise by using the same machine keys on each web server. However, this is not ideal if you wish to SSO across different domains and it's not very neat for windows app that need to come into the web farm to use the web service methods...
So, where we have to do this we are using SAML
But to clean this all up and make it more unified and more secure we are beginning to implement Geneva
If you communicate with the web services and web pages using http post, you avoid putting the info in a query string.
Send the data over https so that it cannot be tappered with.
You then need to make sure that the call is coming from your public web environment. One way of doing this is to use windows authentication, based on the identity of the application pool.
EDIT 1
Take a look at this link: http://www.codeproject.com/KB/WCF/WCFBasicHttpBinding.aspx
It shows how to set up windows authentication for WCF basic http binding.
Maybe look at the HTTP REFERER field. Under certain conditions this may be treated as reliable. In particular: An A mimic site won't send users from A to C according to HTTP REFERER.