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.
Related
really hope that I can get some pointers with this before I go wasting too much time. In truth, I'm not even one hundred percent sure where I need to be asking this. I'm dealing with a whole heap of technologies I've had little to know experience with. Historically, I've been a pretty simple vb.net desktop developer so I'm learning MCV5 & C# as I go. I realize some of this might be in the wrong place, but hoping for pointers at lease
So the situation is I've been asked to develop a web application/api by a number of my customers so that their field staff can perform certain data entry functions while out of the office and periodically feed back into their management systems. All these customer have the very close to the same requirements and management systems, so my my intent is to build a single web application with a multi-tenant database where I control who gets to see what based on their login.
The core of the web app, database(s) etc I've got my head around, in fact that all seems pretty seamless. Using https://msdn.microsoft.com/en-us/library/aa479086.aspx as a start point I think I can manage the database side of things.
Where I'm really struggling over is how best to secure this system. Looking at the options in available to me in visual studio (2015) I think the best option for me is for me to use an On-Premise ADFS. My boss has already put his foot down regarding Azure, so unfortunately not an option, we pretty much have our own server farm in house more than capable of hosting this.
The real sticker here is my SA has pretty much said this is not his problem, if you want ADFS and a web server, you sort it out. He's given me a nice fresh server VM with Win2012R2 at least, but doesn't want anything more to do with it.
So, to the questions
Is ADFS even needed in this scenario, or am I better deal with this
all via a standard AD or some other tooling? And even if it is possible, is it a good idea?
Duringdevelopment/testing, is it ok to use a self signing certificate or
am I going to run into to trouble with certificate errors?
When configuring ADFS, you get asked for the federation Service name. In
the senario above where I'm using it for authenticating a web app,
is it ever exposed directly to the end user? Are they going to be
needing to type this in to their browsers? and will it be better to have external DNS entries for this?
My 2-cent:
There will be a learning curve, but if all the users are stored in AD, using ADFS will give you some advantages such as SSO, federation against other providers if you ever need it later on.
Using self-signed certificates during dev/test is fine. You can turn off certificate revocation check on ADFS side.
No, that Federation service name doesn't get exposed to the end users. I would suggest you have external DNS entries for your ADFS because your users need to access it from the outside. In short, a user rarely needs to type in ADFS url. Instead, he or she needs to access a service provider site and it will redirects he or she to the ADFS site.
This is becoming a more common scenario and can be seamlessly handled with AD FS. Ideally what you would want to do is:
deploy your AD FS farm
Configure your Web Application to trust your ADFS STS
Whenever you need to add a customer who will be using your multi-tenant application, add a federation trust with that customer (i.e. federation trust between your AD FS and the customer's AD FS)
This will ensure that you don't have to deal with identity management for every individual user when you add a customer. When a customer tries to login to your WebApp, then he will be authenticated against his AD FS, and your AD FS will get the token and sign them and present it to the Web Application. This will give them SSO which everyone has started to expect as a de-facto :)
Self signed certificates - As Thuan mentioned it is ok to use them during testing, just ensure that all your test boxes are configured to trust the certificate or otherwise you will be seeing connection drops all around
Federation service name - As explained in the setup summary above, the federation service name will never need to be exposed to the end user from a customer's organization. For all he knows, he is being authenticated against his AD FS as he is used to it already.
You might want to consider deploying AD FS in Azure:
AD FS deployment in Azure
In the context of WCF/Web Services/WS-Trust federated security, what are the generally accepted ways to authenticate an application, rather than a user? From what I gather, it seems like certificate authentication would be the way to go, IE generate a certificate specifically for the application. Am I on the right track here? Are there other alternatives to consider?
What you are trying to do is solve the general Digital Rights Management problem, which is an unsolved problem at the moment.
There are a whole host of options for remote attestation that involve trying to hide secrets of some sort (traditional secret keys, or semi-secret behavioural characteristics).
Some simple examples that might deter casual users of your API from working around it:
Include &officialclient=yes in the request
Include &appkey=<some big random key> in the request
Store a secret with the app and use a simple challenge/response: send a random nonce to the app and the app returns HMAC(secret,nonce))
In general however the 'defenders advantage' is quite small - however much effort you put in to try and authenticate that the bit of software talking to you is in fact your software, it isn't going to take your attacker/user much more effort to emulate it. (To break the third example I gave, you don't even need to reverse engineer the official client - the user can just hook up the official client to answer the challenges their own client receives.)
The more robust avenue you can pursue is licencing / legal options. A famous example would be Twitter, who prevent you from knocking up any old client through their API licence terms and conditions - if you created your own (popular) client that pretended to the Twitter API to be the official Twitter client, the assumption is their lawyers would come a-knocking.
If the application is under your control (e.g. your server) then by all means use a certificate.
If this is an application under a user control (desktop) then there is no real way to authenticate the app in a strong way. Even if you use certificate a user can extract it and send messages outside the context of that application.
If this is not a critical secure system you could do something good enough like embedding the certificate inside the application resources. But remember once the application is physically on the user machine every secret inside it can sooner or later be revealed.
I'm currently thinking how I could protect my REST API which is used only by my mobile application from being used by other applications?
Could a API-Key be a good solution, because just me know the secret API key.
Is there a better solution?
Leon, you keep mentioning "someone else using my API with another application". So, you want to tie your API to be used only by one application? So, you don't want to give access rights to a user, you want to give them instead to an instance of your application running on the user's mobile device.
In essence: You don't trust the user!
Well, in that case you need to make sure your application is closed source, need to code your credentials into your application in such a way that nobody can retrieve them or store the credentials for it in a specially encrypted manner on the device, the decryption key for it being readable only by your application. In a way, you need to implement a form of DRM to prevent people from doing stuff with data on their mobile device. And you need to hope that nobody can reverse engineer it.
If your app becomes popular / interesting enough, count on the fact that people who are very, very good at this sort of thing will look at your application and will break your encryption before you know it. Maybe, if you put the same amount of effort into it as Skype has, maybe then you can ward them off for a while.
But ask yourself: Why bother? Why don't I trust my users? Is it really worth it to jump through hoops like this to prevent some other application from using my API?
Just lead your user through a registration process in which each app instance gets a unique key from the server (or a unique HTTP auth password) and stores that somewhere on the user's mobile device. Then, to access the interesting features in the API, require the presence of this key/password. But don't go through extreme length to obfuscate or encrypt the key when you store it locally, it's not worth it. If you every detect misuse later, you can always revoke the access rights for a particular account on the server anyway.
Use HTTP Authentication. REST is all about using the facilities available in HTTP, so the native HTTP auth should be used. With basic authentication you’ll have to use HTTPS though. If you cannot do that use HTTP digest auth or NTLM.
All of them have different strengths and weaknesses, and not every one of them might be supported by your HTTP server and client library.
I have a PHP application that is successfully authenticating against a CAS server. One of the features supported by the application is impersonation; a user with the appropriate privileges can impersonate another of the application. Generally, this isn't a problem because the app itself can keep track of who the user is impersonating and manage privileges (which are based on username).
A new requirement has come up, though, that requires the original app to include, via an iframe, content from a second PHP app that is also CAS-enabled. Somehow, I need for the second app to know whether impersonation is happening in the first. I don't want to pass usernames around for security reasons, so I'm wondering whether I can offload the responsibility for handling impersonation to the CAS server which is shared by both apps.
Thanks.
I realise this is a very old question, however, CAS as of v5.1 does support impersonation. It's referred to as surrogate authentication:
https://apereo.github.io/cas/5.1.x/installation/Surrogate-Authentication.html
The more we considered this and tried to get something worked out, it seemed more and more likely that this just isn't available in CAS and perhaps shouldn't be. If we accept that CAS's sole purpose is to identify a user and ensure that the user is who they say they are, then it doesn't make much sense to be someone else.
This is just me speculating about the underlying justification, but I feel pretty comfortable saying that CAS doesn't offer impersonation functionality.
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...