From:  Paul Cohen <>
Date:  29 Aug 2008 16:28:10 Hong Kong Time

Undesired XMLHttpRequest 401 behaviour



I am trying to implement a web login solution using HTTP
authentication with:

1. A custom XHTML/CSS/Javascript login form and XMLHttpRequest.
2. Apache 2.2 configuration but no other server side code.
3. No displaying of the browser (Firefox 3.0.1) login dialog.
Eventually I want my solution to work for other browsers, but I am
developing with Firefox.

I have defined a resource named "new-session" that is protected with
HTTP Authentication (Basic) on my server. This resource I get with
XMLHttpRequest when I want to login.

Logging in with a correct username and password works fine. I can
login and Firefox displays no login dialog.

THE PROBLEM: When I login with invalid username or password the login
dialog is displayed. I don't want that. I want my call to
XMLHttpRequest to return with status 401 so I can display my own
custom "Invalid credentials" feedback to the user.

I call:

   /* http is the XMLHttpRequest object */"GET", "new-session", false, username, password);
   http.send ("");

As I understand it the client-server communication in this case is
(with the invalid username = "foo" and password = "bar"):

1. Client -> Server: HTTP GET "
2. Client <- Server: HTTP 401
                            WWW-Authenticate: Basic realm="My Realm"
3. Client -> Server: HTTP GET "
                            Authorization: Basic Zm9vOmJhcg==
4. Client <- Server: HTTP 401
                            WWW-Authenticate: Basic realm="My Realm"
5. Firefox displays the Firefox login dialog.

My main question is: Why doesn't my synchronous call to XMLHttpRequest
simply return after step 4 with status 401 without displaying the
Firefox login dialog? I have to click on Cancel in the Firefox login
dialog before my call returns (with status 401).

Another question is: Why is the username and password sent in the URL?
I know it is in accordance with the HTTP URL scheme but since the
server challenges the client and the client provides the credentials
in the Authorization header there is no need to also send the
credentials in the URL.