Open Bug 411517 Opened 17 years ago Updated 2 years ago

XMLHttprequest loses authentication credentials on calls to different urls

Categories

(Core :: Networking: HTTP, defect, P3)

defect

Tracking

()

UNCONFIRMED

People

(Reporter: schow, Unassigned)

References

()

Details

(Whiteboard: [necko-backlog])

Attachments

(1 file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11

I have 3 directories:

demos/firefox/1/
demos/firefox/2/
demos/firefox/3/

They all have a file named "hello.php" in them.

Each one is protected by it's own .htaccess file which looks like this:

AuthType Basic
AuthName "Woot"
AuthUserFile /path/to/.htpasswd
Require valid-user

(The results are the same if the htaccess file is moved up one directory)

I'm trying to read each hello.php file through an xmlhttprequest connection.   Each X fires off the function that makes the xmlhttprequest call. The call has the user name and password required (schow/schow) as the last two parameters of the open() method.  The callback function just does an alert() of the responseText property.

The URL to hit is constructed using a parameter that's passed to the function.

--- code ---
function executeGet(anId) {

var url = 'demos/firefox/' + anId + '/hello.php';
xmlhttp.open("GET", url, true, "schow", "schow");
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
alert(xmlhttp.responseText);
}
}
xmlhttp.send(null);

} 
--- code ---

Each link that calls the function is in a table, and an onclick event is the trigger.

--- code ---
<td><a href="#" onclick="executeGet(1)">X</a></td> 
<td><a href="#" onclick="executeGet(2)">X</a></td> 
<td><a href="#" onclick="executeGet(3)">X</a></td> 
--- code ---

Reproducible: Always

Steps to Reproduce:
1. Click on one of the X's. 
2. Click on a different X.  Should get a user/pass auth button
3. Dismiss the dialog box via the Cancel button.
4. Click on the same X.
Actual Results:  
When you first click on an X, it will execute correctly. If you click on the same X again, it will also work correctly.

If you click on a different X next, an HTTP authentication window will pop up. If you dismiss that window and click on any of the links, it will work. If you manually enter the authentication credentials, it will work, but the next time you click on a different link, the window pops up again. It will pop up even if you tell Password manager to remember it.

Live HTTP headers show that on success, the request is made, 401 is sent, then Firefox resends the request with the credentials. On failures, the 401 is sent, but Firefox never resends with the credentials. Even on failures, though, Firefox is making the request as http://user:password@server.domain.


Expected Results:  
Firefox should successfully negotiate the authentication requests on second clicks.

If you manually go to the URLs, http://www.shuchow.com/demos/firefox/1/hello.php, /2/hello.php, etc, the auth window will pop up.  If you enter the same credentials used in the xmlhttprequest open method (schow/schow) the auth succeeds and Firefox remembers it on subsequent link clicks. 

This was tested in the latest FF 2 releases on Mac/Win and FF 3 Beta 2.  All exhibit the same behavior.

Successful authentication occurred with IE 5-6 (not tested in 7), Opera 9.2x on Mac/Win, and Safari 3 on Mac/Win.
This is the Live HTTP log of what happens when I click on an X (success), then click on a second X (failure).
HTTP Log of the success followed by failure is here:

http://www.shuchow.com/demos/firefox/firefoxhttplog.txt  (357 kb)

Also, it should be noted that the server is Apache 2.0.55, but it also occurred on a 1.3.x server.
One more note... in another internal test case, I found that this also happened with PUT and DELETE methods (this is being used in a REST web service).  POST was not tested.
Component: Security → Networking: HTTP
Product: Firefox → Core
OS: Windows XP → All
From RFC 2617

"A client SHOULD assume that all paths at or deeper than the depth of the last symbolic element in the path field of the Request-URI also are within the protection space specified by the Basic realm value of the current challenge. A client MAY preemptively send the corresponding Authorization header with requests for resources in that space without receipt of another challenge from the server...."

Note, this applies only to Basic Auth.  Digest auth should default to the whole domain (which I believe Firefox doesn't do).
I ran into the same problem when I was creating a Rest/ajax app.  I had to become "unrestful" by moving away from http auth in the app.  As proper Rest practices becomes more prevalant, this bug will be a bigger issue.
I don't believe this is a bug (with regard to Basic Auth).  The RFC states that a browser SHOULD do this.  You can establish a wider range for the realm by doing a request on a resource higher up the hierarchy.

Now as for this behavior when doing Digest Auth.  That is a bug.
To test Tim's assertion, I put in a call at onload to fetch a dummy document via xmlhttp.  This dummy document sits at the same level as the 1/2/3 directories.  After that, firefox successfully authenticated subsequent requests to documents underneath the 1/2/3 subdirectories.  This is a work around to the issue.

However, I believe this is still a bug.  

1) Accessing some dummy resource instead of the main resource is counter to REST principles.  The document above my resources isn't anything, but I'm forced to put it there and make a useless retrieval to it at the start of my page load?
2) There is a discrepancy between how xmlhttprequest is authenticating and manually entering in the URLs.  As I reported, manually entering in the URL in the Address Bar authenticates successfully when you switch URLs.  xmlhttprequest does not.

(In reply to comment #4)
> Note, this applies only to Basic Auth.  Digest auth should default to the whole
> domain (which I believe Firefox doesn't do).
> 

I just tested Firefox 2.0.0.12 and it does default to the whole domain when using digest auth (which is the right thing to do)
There might be a problem with basic authentication under SSL, too.

I describe a work around that I'm doing in Comment #7, using Tim Olsen's assertion that a call to a higher level resource is needed.  When this is not under SSL, it works fine.  However, under SSL, the original error occurs.  Firefox receives an HTTP 200 message from the dummy retrieval, but then after that, I get the same authentication errors as before when switching resources.
QA Contact: firefox → networking.http
Whiteboard: [necko-backlog]
Bulk change to priority: https://bugzilla.mozilla.org/show_bug.cgi?id=1399258
Priority: -- → P1
Bulk change to priority: https://bugzilla.mozilla.org/show_bug.cgi?id=1399258
Priority: P1 → P3
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: