Authorize the REST web service
webdev pythonOnce 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.