WCF and wsHttpBinding - Message encryption - c#

I'm working on a client-server project implemented using WCF. The clients are deployed on different machines and communicate with services through the internet. I'm relatively new to WCF, and am a bit confused on choosing the appropriate binding for my Web services. The clients need to be authorized to perform operations, however, I'm implementing my own authentication algorithm and trying to avoid Windows authentication for various reasons, but I still need to make sure the message transferred in the channel is encrypted.
Right now I'm using wsHttpBinding with security mode set to Message. Full configuration looks like this:
I've set the authentication type in IIS to Anonymous Authentication to make sure the requests are passed through, and was expecting a service call to fail since MessageClientCredentialType in my binding is explicitly set to Windows. However, when I run the code, the service successfully gets called and returns the expected values. I have a feeling that I'm missing something - why is the call authorized? Can I make sure the message is still encrypted even though authentication type is set to Anonymous? Any help is appreciated.
Edit
To clarify on this, I tested the service with a client deployed to a machine outside the network on a different domain.

This MSDN article kind of sums up a lot of security issues relevant to WCF
http://msdn.microsoft.com/en-us/library/ms733836.aspx
regarding your specific situation,
the negotiateServiceCredential="true" means that you streamline certificate distribution to your clients for message encryption.
This option will only work with windows clients and has some performance problems.
read more here http://msdn.microsoft.com/en-us/library/ff647344.aspx
search the topic "streamline certificate distribution" in this page.

Which account do you use to make the call to the service? Allowing anonymous in IIS lets your request pass through to the service and service should authenticate if your caller has credentials that windows understands (Active directory/NTLM).
In your case, I think you are testing it in your own environment so service responds. Once you deploy it over internet, I doubt your service will allow anybody outside of your domain if you keep clientcredentialtype to windows.
Check these link for securing services on the Internet -
http://msdn.microsoft.com/en-us/library/ms734769.aspx
http://msdn.microsoft.com/en-us/library/ms732391.aspx

Related

Secure WCF service from unauthorized use

this is a similar question but doesn't fit my needs: WCF - Preventing Unauthorized Clients
I have full control over both a WCF Service and a number of clients that connect to this service.
Every client is just a program that doesn't require any username or password.
I want to be totally sure that only my clients will connect and use my WCF Service, is this possible?
My WCF Service uses 2 type of endpoints: netTcpBinding and basicHttpBinding.
Since i'm totally new to this kind of problem i'm googling and finding answer about using certificates, but i don't know if this is the right answer to my problem (and don't know of to use them). If certificates are the only way i'll use all the needed time to understand how to use them :)
Thank you!
Some sort of authentication is required, which sort is very much context dependent.
If you're in a windows domain, I would suggest using those mechanisms. Either way you should probably start here: http://msdn.microsoft.com/en-us/library/ff405740.aspx

prevent cross domain requests to my wcf services

I use wcf ui services communicate between my javacsript (jquery) and server side code. I find this work effectively.
However I want to make it more secure. I can I set up wcf so that the requests to the services can only be made from within the same domain, to prevent external clients from making such requests to my services.
So for example, my service opertion url is http://www.website.com/Service.svc/GetProducts. I want to set up wcf so that only requests from pages in the http://www.website.com are allowed. I presume this is in the realm of cross domain wcf requests but need some assistance in setting this up. Help would be great.
This simply isn't possible if your services are exposed to the web.
If something about your services isn't secure enough for that, you should look into fixing that problem - not trying to prevent people from making requests.
Anyone can always use a debugging proxy like Fiddler, Charles, etc. or a tool like WireShark to send any data they want to your services - including a complete replay of a request made via the browser. (Including referrer http headers, etc).
If your situation allows for it, perhaps you might consider using a VPN appliance or something similar, and restrict access to users inside your network (or coming in through the VPN). That way there is less concern about your security of the services.... however it's a known fact that "internal attackers" are just as prevalent, if not more so, than external ones... so don't get too comfy.
Let me head this argument off at the pass too, while I'm at it; someone might suggest that browsers already prevent cross site scripting like that. Yes, that's true. But usually it would be the developer of the other application adding the client side script to call those services - and he/she could just as easily make that request on the server side and proxy the results along to the client.

Windows network authentication the right way

I am about to start on a project that will be running as a windows service listening for incoming connections and doing some things locally then sending a reply message. I understand the basic concepts with sockets and communicating over the network, however the things the service are doing could very easily abused. I would like to authenticate the person connecting, preferably against the windows local users on the machine the service is running, to see if they have windows administrative/power user rights.
I know how to do it check the rights once I have their information but I know sending the user name and password to the application over the network in the clear is a no no. I was thinking of just encrypting the password with some secret key but I know "trying to be clever" is the worst possible thing you can do in cryptography so I wanted to know what is the "correct" way to handle this situation.
My second idea was just create a shared self signed certificate between the client and the server and just use TLS for the entire connection.
I may as well post what I was thinking of doing, if it is the right thing to do say so in the comments.
Both the client and server will have a PSK at run-time the server will send a random number to the client. the client will encrypt the credentials with the PSK and the random number as the IV. It will send back the encrypted blob plus whatever commands it needs done.
I am not concerned about replay or mitm attacks. I just want to authenticate the user and not have peoples passwords blasted all over the network.
Scott,
this may be a bit overkill and a bit off topic, but have you considered using a web service interface to serve your clients (instead of using raw sockets)?
ASP .Net web service interfaces are easy to implement, and in the end, you'll end up with a very well defined interface. They also have support for authentication and secure communication.
ASP .Net Web Service Tutorial
HTTP Security and ASP.NET Web Services

Cross-network WCF service authentication - What's the best way to do it?

I have a WCF service that's hosted at a commerical hosting facility that I need to authenticate against Active Directory on my corporate network.
I should mention that there is no way to setup an AD-Trust between the two networks. Also, my corproate IT department sucks so any solution will likely need to be crafted and/or implemented by me. In the worse case scenario I can host a custom authentication service on my corporate servers that the hosted WCF service would call to do authentication but I'd prefer to use a pre-built or (at the very least!) industry standard way of accomplishing my requirements.
Any help in this regard would be greatly appreciated....
I don't think this will work out of the box - you'll have to write some code.
The issues are:
Get a connection from the hosting machine to something on your network
Get the something on your network to talk to Active Directory
I don't know enough about WCF to supply details, but I know that it's possible to completely customize authentication. You would need to have your custom authentication communicate to a service on your network (probably using WCF and some very secury configuration). This service would take the username/password from the hosting provider and pass it to Active Directory to validate.

Problem Connecting to WCF Service on a Server

I have set up a WCF service on a server which lives in its own Workgroup. I've tried to make a TCP/IP connection to it from a client that lives on the corporate domain. When I try to open a connection, I get a SecurityNegotiationException with the message:
"A remote side security requirement
was not fulfilled during
authentication. Try increasing the
ProtectionLevel and/or
ImpersonationLevel." The inner
exception reads: "The network logon
failed"
After speaking with some coworkers about the issues and performing some google research, I came to the conclusion that the issue is that the client is attempting to log on to the server using my corporate network login and password. Since the server is not part of the corporate network, it has no knowledge of my corporate identity and then rejects the login / connection attempt. Whether this analysis is correct or not, I have no idea.
Google results seem to suggest that perhaps the solution is that I need to impersonate user account that exists on the server machine. --I have also stumbled across this codeproject article which demonstrates user impersonation. Since the only account on the server is Administrator with no password, I tried domain as the computer's ip address as "10.0.0.11", username as "Administrator", and password as "".
http://www.codeproject.com/KB/dotnet/UserImpersonationInNET.aspx?display=Print
Unfortunately, it fails with the message:
"Logon failure: unknown user name or bad password"
Another hint to the problem: When the client and server are both machines on the corporate network, there are no connection problems at all.
How can I resolve the error and complete the connection to the server?
Even though it is not a best practice, I am completely okay with removing any security so I can keep this project moving forward
Until you grasp the details, best way to learn is to disable security. You have to create a new binding configuration at the server side with security mode set to "None". Name it "NoSecurity" for convenience. This configuration must have the same type (wsHttpBinding, etc.) you use at your endpoint. Then set the bindingConfiguration property of your endpoint to "NoSecurity".
Update your client configuration and you are set to go.
I know of no way to have a workgroup trust a domain, which means you have a couple of choices, as i see it
Add another endpoint in your WCF service that uses HTTP (a web service endpoint) and use this from the domain. This gets around the security problem, as you can impersonate here, or even set up a specific user that can access goodies in your workgroup server.
Whack down security in the WCF service. i would have to think about how to do this, but it is not a good idea anyway.
Create a domain and get a trust relationship.
The code project you mentioned is not dealing with impersonation in a way that is directly useful to WCF, as the authentication happens before you can even hit this code. I imagine you can whack at the framework bits to do it, but that would be nasty. There might be a way to use the code in an HTTP endpoint, but that can already be done without incurring the overhead of adding code that circumvents windows security.

Categories