I have designed a REST web service which requires authentication. It handles authentication in a manner similar to Amazon Web Services, namely: the user has an ACCESS_KEY
(say, 'abcd') and a SECRET_KEY
(say, 'aabbcc'). The SECRET_KEY
is used to create a TOKEN
: a SHA-1 using the request information, for example:
GET path HTTP/1.1
Date: Mon, 23 May 2005 22:38:34 GMT
ACCESS_KEY: abcd
TOKEN: SHA1(SECRET_KEY + ACCESS_KEY + Date + path)
I can check the TOKEN
in the server and authenticate the request. Up to this point, I don't think there is anything wrong with the security model.
My only question, is how to provide the SECRET_KEY
when using the service from a web page. I thought I could send it as a JavaScript variable (the connection is HTTPS) and simply use that variable in a JavaScript function that adds the appropriate header to every HTTPRequest
. The initial authentication can be done using standard cookie-based approaches (for instance, relying on Django to handle a session).
So, the architecture looks like:
- Web site session: handled by Django using standard session-based security (
example.com
) - The web site session receives via HTTPS the
SECRET_KEY
as a JavaScript global variable, which is used to add the appropriate headers to everyHTTPRequest
. - The
HTTPRequests
are made toapi.example.com
, which is oblivious to the Django session: it only cares about having the appropriate headers.
I believe this approach is secure, while maintaining a completely stateless REST API. I don't use standard HTTP authentication (basic or digest) because I don't want to hack the "you cannot logout" problem, and I want to keep the API strictly REST.
Do you have any comments regarding this approach? If it is flawed, how would you accomplish my goals?
Thank you!