Authorize the REST web service

webdev python

Once we step into the REST territory, session-based AuthenticationMiddleware is no longer an option due to the violation of stateless principle. Digest authentication seems one of the very few options left for this situation. The basic concept is that the client and server share a private secret key, the client signs the HTTP request and the server validates the signature before further operations.

There is no off-the-shelf digest authentication middleware available yet, let’s roll up sleeves and home-brew our own or more specifically, shameless copy the S3(authentication spec) python library with slightly simplification:

The entities under the radar are cut to five: HTTP verb, Content-Length, Content-Type, Date and the body. The HTTP verb and content type specify the REST request, the date prevents the man-in-the-middle replay attack. The signature is then digested on the stream, and appended into Authentication header.

Update: URL is also essential, the man-in-the-middle may record the REST operation in one entry, and replay in another entry point.

It is also pretty straightforward to wrap up the digest authentication as a middleware: create a new model named as Token and add access_id and access_key pair, also the User as foreign key. We could just copy AuthenticateMiddleware and override get_user method to integrate the digest validation. You may check the revision 21 to 22 on pattee for more details if you are interested in.

There is another issue worthy our attention: both digest and session-based authentications are required, the latter is the gate keeper to access admin interface to manages the token used for the former, but they may not play well together: the resource for the cookie management in the server side is totally wasted to handle REST requests, and furthermore, it leaves the door open for security exploit by stolen cookies. We will discuss this issue later, stay tune.