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:
for example: 3 June 2011
then concatenate with user password, example "my4wesomeP4ssword!"
Then do MD5 of that string:
When do you call a request, always use this token,
This token is always unique everyday, so I guess this kind of protection is more than sufficient to always protect ur service.
Hope helps
:)
You can create Session on server and share
sessionId
in between client and server with each REST call.First authenticate REST request:
/authenticate
. Returns response (as per your client format) withsessionId: ABCDXXXXXXXXXXXXXX
;Store this
sessionId
inMap
with actual session.Map.put(sessionid, session)
or useSessionListener
to create and destroy keys for you;Get sessionid with every REST call, like
URL?jsessionid=ABCDXXXXXXXXXXXXXX
(or other way);HttpSession
from map usingsessionId
;There are several different approaches you can take.
The RESTful purists will want you to use BASIC authentication, and send credentials on every request. Their rationale is that no one is storing any state.
The client service could store a cookie, which maintains a session ID. I don't personally find this as offensive as some of the purists I hear from - it can be expensive to authenticate over and over again. It sounds like you're not too fond of this idea, though.
From your description, it really sounds like you might be interested in OAuth2 My experience so far, from what I've seen, is that it's kind of confusing, and kind of bleeding edge. There are implementations out there, but they're few and far between. In Java, I understand that it has been integrated into Spring3's security modules. (Their tutorial is nicely written.) I've been waiting to see if there will be an extension in Restlet, but so far, although it's been proposed, and may be in the incubator, it's still not been fully incorporated.