HTTP Basic Authentication and your URL hierarchy
We're big fans of Apache's implementation of HTTP Basic Authentication, but we recently discovered that there are
some subtle implications of how Basic Authentication can interact
with your URL hierarchy within a web application. This is because of when HTTP
Basic Authentication is and isn't sent to you,
and specifically that browsers don't preemptively send the
Authorization
when they are moving up your URL hierarchy (well, for the first
time). That sounds abstract, so let's give a more concrete example.
Let's suppose you have a web application that allows authenticated
people to interact with it at both a high level, with a URL of
'/manage/', and at the level of dealing with a specific item, with
an URL of say '/manage/frobify/{item}'. You would like a person to
frobify some item, so you (automatically) send them email saying
'please visit <url> to frobify {item}'. They visit that URL while
not yet authenticated, which causes the web server to return a
HTTP 401
and gets their browser to ask them for their login and password on
your site (for a specific 'realm', effectively a text label). Their
re-request with an Authorization
header succeeds, and the
person delightedly frobifies their item. At the end of this process,
your web application redirects them to '/manage/'. Because this
URL is above the URL the person been dealing with, their browser
will not preemptively send the Authorization
header, and your
web server will once again respond with a HTTP 401.
Because this is all part of the same web application, your HTTP
Basic Authentication
will use the same realm
setting for both URLs in your web server
and thus your WWW-Authenticate
header. In theory the browser can see that it already knows an
authentication for this realm and automatically retry with the
Authorization
header. In practice a browser may not always
do this in all circumstances, and may instead stop to ask the person
for their login and password again. With this URL design you're at
the mercy of the browser to do what you want.
(This can be confusing to the person, especially if (from their perspective) they just pressed a form button that said 'yes, really frobify {item}' and now they're getting challenged again. They may well think that their action failed; after all, successful actions don't usually cause you to get re-challenged for authentication.)
Unfortunately it's hard to see how to get out of this while still having a sensible URL hierarchy, short of never sending people direct links for actions and always having them enter at the top level of your application. One not entirely great option is that when people frobify their items, they are never automatically redirected up; instead they just wind up back on '/manage/frobify/{item}' except that now the page says 'congratulations, you have frobified this item, click here to go to the top level'. This is slightly less convenient (well, if people actually want to go to your '/manage/' page) but won't leave people in doubt about whether or not they really did successfully frobify their item.
When you look at your logs, this behavior may be surprising to you if you've forgotten the complexities of when browsers preemptively send HTTP Basic Authentication information. HTTP Basic Authentication doesn't work like a regular cookie, where you can set it once and then assume it will always come back, which is the model of authentication we're generally most familiar with.
|
|