It seems so simple: use the HTTP Digest Authorization with the Quality of Protection set to "auth".
It's an easy algorithm. A nonce that encodes a timestamp can be used to be sure no one is attempting to cache credentials. It's potentially very, very nice.
Except for one thing: Apache.
Apache absorbs the Authorization header. And that's the end of that. It seems so simple, but I think I've been burned by it twice, now. I write unit tests that work with simplified Python wsgiref (or similar) servers. And I believe that those unit tests are equivalent to integration tests.
There's another reason why HTTP Digest authentication for RESTful services is a poor idea.
It involves too much traffic. HTTP authentication is usually a two-step dance to establish a session. Two steps in one too many, and RESTful services don't usually have any kind of session.
The comments on this post are almost as helpful as the post itself.
The three points are straight-forward.
- Use SSL. Always.
- Multiple Key/Secret credentials. Read this as username/password if that's helpful. We store hashes of "username:realm:password" as part of a RFC 2167 Digest Authentication. We plan to continue to use those hashes. This is a bit touchy, but we think we can handle this by a slight change to our user profile table.
- The "signed query" principle requires some thought. We don't make heavy use of query strings. Indeed, we make almost no use of the query strings. So the hand-wringing over this is a bit silly. We simply ignore any query string when signing the request.
I just wish I did integration testing with Apache sooner, not later. Sigh.