Sponsored Link •
HTTP Authentication may be RESTful, but it's not very USEful.
Whenever I talk to a REST enthusiast, they tell me I should be using HTTP authentication, not forms with cookies or URL-rewriting, for user authentication. (REST is an architecture style for distributed systems, and a popular way to think about the web.) Most web frameworks, including Java servlets, use one or both of these approaches to make it easy to identify a server-side session object for a given request. A RESTful application, however, would model all server-side state as resources accessible via URIs, so there's no need for that session object. The URL-rewriting is particularly anti-REST, because a single resource has many URIs, one for each session ID. Both approaches, especially when combined with a server-side session data, tend to erase much of the scalability benefits of HTTP 1.1's caching mechanisms.
Nevertheless, HTTP authentication is not widely used. The two approaches currently defined in the specifications are HTTP "Basic" and "Digest" authentication. Basic is widely supported, but because it effectively transmits the username and password in the clear, it is usually appropriate only over HTTPS. Digest never sends the password in the clear, but is apparently not implemented consistently in clients. In his recent XML.com article, httplib2: HTTP Persistence and Authentication, Joe Gregario describes the interoperability issues with Digest in more detail, and concludes:
The bad news is that current state of security with HTTP is bad. The best interoperable solution is Basic over HTTPS.
With HTTP authentication, the client (such as a web browser) presents its own authentication dialog to the user when prompted for credentials by the server, after an initial request of a resource that is in a protected realm. (A realm is a URI, such as "/admin" and all resources under that URI, such as "/admin/moderation" and "/admin/users".) The user enters their username and password into the dialog, thereby authenticating themselves to the client for the requested realm. The client then uses those credentials to authenticate with the server for that realm from then on, until the client is exited. (I.e., there is usually no way to log out of a client authentication except by ending the client process.)
Being a budding REST-enthusiast myself, I investigated HTTP authentication, but discovered several usability and a few security concerns:
With HTTP authentication, the client takes the credentials, usually a username and password. This means that the application has no control over what prompt is given for username. At Artima, we are planning to have a network of sites with single sign on, and a while back I took to calling the username "Artima ID" on our sign in page (just as Yahoo calls their login a "Yahoo ID"), to make it obvious what you're logging into. The C++ Source will someday be its own website, but to sign in you will need to use your Artima ID. You won't have a The C++ Source ID. My first concern is that the inability for me to put "Artima ID" next to an empty box for the username with HTTP authentication, will cause people to be confused about what to type there.
Moreover, email addresses are now unique in our database, so if you forget your Artima ID, I'd like to let you use any of the email addresses you attached to your account instead of your Artima ID. And in fact, I may have registration paths where you don't select an Artima ID, so you may not have an ID even if you have an account. So I may want to say "Artima ID or email address:" next to that empty box, or at least a note explaining that if you've forgotten your ID, you can use your email. If people are authenticating via the client's authentication dialog, I believe it would be harder for me to explain that.
If you have forgotten your password, I have on the sign in page a "Forgot your password" link to a way to deal with that problem. It is not as easy to make that option clear using the browser's HTTP authentication dialog.
If you don't have an account yet, I have on our existing sign in page a "Sign Up" link to a path that allows you to create a new account. It is not as easy to make that path obvious when using the client's HTTP authentication dialog.
With HTTP authentication, I can force the user to sign in before doing things that require being signed in, like posting to a forum or administration. However, I also want to be able to recognize via the request whether or not the user is signed in. If not, I don't want to force them to sign in, and instead will return a representation for guests. If they are signed in, I want to return a personalized representation of the resource.
With cookies or URL-rewriting, I can quite easily enable users to sign onto the entire network of artima.com subdomains in one shot. In HTTP Digest authentication, I can explicitly list domains that are included in the realm, but not with Basic. However, the scalability of listing each subdomain individually with Digest is a scalability concern. It works fine for half a dozen subdomains, but what about 100 or 500?
Users are accustomed to having a log out button that enables them to log out of a site before leaving a public terminal. The HTTP authentication protocols provide no way for the server to request that the client erase the credentials for a realm other than prompting for them again, which causes the browser to pop up the dialog again. Today's browsers do not themselves provide a way to log out of a realm, other than quitting the browser.
Despite the presence of potential workarounds, I find HTTP authentication in its current state to be too much trouble to use. I am still planning on using a cookie as an authentication token in our new architecture, or if cookies aren't enabled, URL rewriting. I'm curious if others have any success stories, or the opposite, to share about using HTTP authentication in practice.
|Bill Venners is president of Artima, Inc., publisher of Artima Developer (www.artima.com). He is author of the book, Inside the Java Virtual Machine, a programmer-oriented survey of the Java platform's architecture and internals. His popular columns in JavaWorld magazine covered Java internals, object-oriented design, and Jini. Active in the Jini Community since its inception, Bill led the Jini Community's ServiceUI project, whose ServiceUI API became the de facto standard way to associate user interfaces to Jini services. Bill is also the lead developer and designer of ScalaTest, an open source testing tool for Scala and Java developers, and coauthor with Martin Odersky and Lex Spoon of the book, Programming in Scala.|