I am designing a RESTful web service that needs to be accessed by users, but also other web services and applications. All of the incoming requests need to be authenticated. All communication takes place over HTTPS. User authentication is going to work based on an authentication token, acquired by POSTing the username and password (over an SSL connection) to a /session resource provided by the service.
In the case of web service clients, there is no end user behind the client service. The requests are initiated by scheduled tasks, events or some other computer operations. The list of connecting services is known beforehand (obviously, I guess). How should I authenticate these requests coming from other (web) services? I want the authentication process to be as easy as possible to implement for those services, but not at the cost of security. What would be the standard and best practices for a scenario like this?
Options that I can think of (or have been suggested to me):
Have the client services resort to having a "fake" username and password, and authenticate them in the same way as users. I do not like this option - it just doesn't feel right.
Assign a permanent application id for the client service, possibly an application key as well. As far as I have understood this is just the same as having username + password. With this id and key, I can either authenticate each request, or create an authentication token to authenticate further requests. Either way, I do not like this option, because anyone who can get a hold of the application id and key can impersonate the client.
I could add an IP address check to previous option. This would make it harder to perform fake requests.
Client certificates. Set up my own certificate authority, create root certificate, and create client certificates for the client services. A couple of issues come to mind, though: a) how do I still allow the users to authenticate without certificates and b) how complicated is this scenario to implement from the client service point of view?
Something else - there must be other solutions out there?
My service would be running on Java, but I deliberately left out information about what specific framework it would be built on, because I am more interested on the basic principles and not so much on the implementation details - I assume the best solution for this will be possible to implement regardless of the underlying framework. However, I am a bit inexperienced with this subject, so concrete tips and examples on the actual implementation (such as useful third party libraries, articles, etc.) will be much appreciated as well.
After reading your question, I would say, generate special token to do request required. This token will live in specific time (lets say in one day).
Here is an example from to generate authentication token:
(day * 10) + (month * 100) + (year (last 2 digits) * 1000)
for example: 3 June 2011
(3 * 10) + (6 * 100) + (11 * 1000) =
30 + 600 + 11000 = 11630
then concatenate with user password, example "my4wesomeP4ssword!"
11630my4wesomeP4ssword!
Then do MD5 of that string:
05a9d022d621b64096160683f3afe804
When do you call a request, always use this token,
https://mywebservice.com/?token=05a9d022d621b64096160683f3afe804&op=getdata
This token is always unique everyday, so I guess this kind of protection is more than sufficient to always protect ur service.
Hope helps
:)