How to secure a WCF service to be consumed by a specific application only? - wcf

I have a specific Silverlight application, that is fed with data by a WCF-Service. I want to make sure, that the WCF-Service is only called by that specific Silverlight App. What is the best way to accomplish that and what do I have to do? It doesn't have to be a high security solution.
Thanks in advance,
Frank

Enable basic authentication (username/password) on the service. Create a single user which the Silverlight app will use to authenticate itself with the service.
Easier, but less secure, might be to just use some sort of identifier (only known to the Silverlight client) as a service parameter.
Both options are obviously most secure when implemented with HTTPS. This can be accomplished by using a server certificate.

You CANNOT restrict access to such a service. Your app will need access to whatever key/password you chose. It is trivial to decompile your app and extract the key. SSL/TLS will not help - because the password can be extracted from the compiled code.
This question has been asked quite a few times recently -
Ensure exclusive access to webservice
How to restrict access to my web service?
How can I create and use a web service in public but still restrict its use to only my app?

If your application is running anonymously then it's virtually impossible to be 100% secure.
How ever if your are requiring your users to authenticate then you should be able to make the service relatively secure by requiring their login credentials...

I don't know if it easy with WCF, but I guess you could do something using client certificates. I only used this approach for protecting websites and it was quite easy to do...

Related

Need help in implementing WCF authentication and authorization in internet context

I need to create a wcf service which would be consume by silverlight apps downloaded through internet. Basically the users are not part of any windows domain but there credentials and roles are maintained in database.
The wcf service should be internet enabled, but methods cannot be accessed anonymously.
Authorization should also be supported\
User and roles tables are not as per ASP.NET membership schema
Developers should not be constrained to have IIS installed and certificate configured
Authorized users should be able to access only his related information. He should be able to delete or update his related companies but not others.
To achieve 1 & 2, i had followed below link.
WCF security by Robbin Cremers
To cover point 3, i have provided custom implementation of MembershipProvider and RoleProvider classes and overridden methods ValidateUser and IsUserInRole respectively to fetch from my own schema user and roles table.
So far, so good authentication and authorization works fine.
Now the problem, the developers can't have IIS installed and certificates configured, so need to disable this in development mode. Hence have implemented custom CodeAccessSecurityAttribute class which would check development mode or production and use custom IPermission or PrincipalPermission.
[Question 1]My question is I don't anywhere people recommend this approach, so litte afraid whether this is the right approach or any better approach is there to handle this situation.
[Question 2] Lastly related to point 5, do i need to send some kind of token over? What is the best approach for this?
[Question 3] Performance impact in Robbin Cremers method, since for every service call, two extra database calls will be made in "ValidateUser" and "IsUserInRole" to authenticate and authorize. Is there a better way?
Sorry for the big question.
As far as I can tell from your scenario description, once you've created and hooked up your custom Membership / Role providers, you don't really need Message Security. Instead, the standard approach described in http://msdn.microsoft.com/en-us/library/dd560702(v=vs.95).aspx will work just fine (or http://msdn.microsoft.com/en-us/library/dd560704(v=vs.95).aspx if you want users to log in via your Silverlight app instead of via a regular web page). The browser then handles the sending of any required tokens automatically (via cookies), and I'm guessing ASP.NET is smart about caching authentication/authorization results so the overhead should not be incurred on every call.

Authentication mechanisms for an application

What are the best practices if I want my application to authenticate itself to other services?
Let's say I want my application (the programming language doesn't matter) to access a file share or a repository but I don't want to ask the user for password. In addition, I don't want to store passwords in the code of my application. What else can I do? Till now I found only 2,5 options:
1.use Integrated Windows Authentication - but this will, obviously, work on windows only
2.use client certificates and let the service verify them before allowing access
3.use LDAP/RADIUS/CAS with client certificates
is there something else?
There is always good old Kerberos. A little old and stuffy but probably a very interesting contender for what you are trying to do.

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.

Authenticating Users via Restful WCF services on Azure IIS Server

I'd like to write a mobile location based application (iPhone, Andorid and BlackBerry) that will get and post data to my web server (hosted on Azure IIS) via WCF restful services.
What is the best way to authenticate my users?
REST authentication can be done custom (like API key auth), or using something like Basic Auth or OAuth. It depends slightly on the interaction you want. You can certainly use ACS to pretty easily secure a REST based service. However, this depends again on what you think you will have in terms of interaction.
As a starting point, I would look here at least (http://acs.codeplex.com/) to see how to use ACS and get started.
I'm doing something similar and I'm using encrypted tokens in my headers.
I'm sure there's a "standard" way of doing that sort of thing, but it was a lot easier just doing it myself.
Basically just using a shared secret to encrypt and a bit of:
WebOperationContext.Current.OutgoingResponse.Headers.Add("sec-token", WebSecurity.CreateToken(blah));
and
string inputToken = WebOperationContext.Current.IncomingRequest.Headers["sec-token"];

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.