Give Authentication a REST!
I hate session-based authentication. I mean, I really hate it. It’s not secure. It also disregards the HTTP standards for authentication, and goes against the intended architecture of the web.
Why isn’t it secure? Because a session uses some kind of cookie or token that identifies your session to the server, and someone can conceivably steal that token and hijack your session. Sure, you can try that “bind to IP address” workaround that a lot of sites are using, but even so - there will always be some way to overcome this, and a session-based authentication system has no guarantee that the user has provided a secret that concretely verifies their identity.
In contrast, HTTP authentication (when properly implemented) does provide this guarantee. It does this by sending the aforementioned secret in headers with each request. Over a secure connection, these headers cannot be snooped or otherwise stolen, and the secret is safe. HTTP Basic authentication goes one better - it sends the precise secret that was entered by the user, and this can be really useful; for example, an application on the server could use this credential to form authenticated credentials to other services.
Let’s look at a common example: a database-driven web application that has a public portion that displays content, and a private portion that manages that content. If the public portion could only read the database, while the private portion could read and write to it, then this would be really secure. You could use separate database credentials for the public and private portions of the application. However, as long as any credentials are stored on the server, they are not secure! If someone gets even read access to the file that stores the secret, they can wreak havoc in your application. That’s why getting the secret from the user on each request is so useful - the credential is not stored on the server, and it is guaranteed that it was provided by someone who knows that secret.
However, HTTP authentication suffers from horrible usability problems. First, the user is presented with an intimidating dialog box for login. This goes against the existing standard - which, unfortunately, is defined by applications with session-based authentication; these applications have nice, integrated web forms that are easily identified as part of the application, rather than an anomalous dialog box. Second, HTTP authentication has no mechanism for logging out, short of closing the browser.
This presents me, the web developer, with something of a dilemma. My users want a nice looking form and the ability to log off. I want my application to be secure, and I want to conform to HTTP specifications. I cannot simply tell my users to deal with the usability issues; sure, I could explain to them about the dialog box and how they must close their browser to log off - but they won’t understand why they must do this, and will see it as an annoyance. This will put my application at a competitive disadvantage. I have seen some attempts at workarounds using XMLHttpRequest to perform HTTP login via a nice form, and even to attempt to logout - but these are far from seamless, and not robust enough for a production web app. In the end, I am obliged to give my users what they want, and this means giving in to session-based authentication; my users don’t understand security enough to care about it, so it becomes a secondary concern. And this is unfortunate.
So this is a call to the W3C: we need better HTTP authentication. We need both HTML and HTTP to be changed in order to accomplish this.
First, we need to be able to submit HTTP authentication information from something like an HTML <form> element. I like the <authform> idea specified in this W3C note, but unfortunately I’ve seen no evidence of this even being considered for adoption.
Second, we need an alternative or alteration to the WWW-Authenticate header that specifies that the authentication prompt will be presented in the response body, and should not be displayed as a UA dialog box. This could be an extra parameter to WWW-Authenticate, or an additional header - either way would allow legacy UA’s to fall back on the UA dialog and still successfully authenticate.
Third, we need a mechanism for instructing the UA to discard its authentication credentials. I personally think that the UA should do this when it receives a 403 in a realm for which it currently has credentials. However, specification does not dictate this, and while most UA’s do this, some (Safari) don’t. Therefore, I suggest a more specific approach: something like a WWW-Deauthenticate, or some such header; upon receiving this header, the UA would discard the authentication credentials and stop transmitting them with each request.
This is also a call to UA developers. We need HTTP authentication to be fixed. Please fast-track this and give authentication a REST.
Leave a comment
You must be logged in to post a comment.