Why do browsers not send the Authentication header

2019-02-17 08:42发布

问题:

I would like to give users the opportunity to do a per-request-authentication by providing the username and password in the URL. As the request is secure, I have no concerns on that.

I tried to call the request http://user:password@localhost/ using a usual browser, (Firefox, Chrome, Safari and Opera was the ones I tested) and I got a 401 response back. When I tried the same URI, but this time provided the credentials as HTTP-header like Authentication: Basic dXNlcjpwYXNzd29yZA==, it worked.

When searching for that, I found this answer to another question: https://serverfault.com/questions/371907/can-you-pass-user-pass-for-http-basic-authentication-in-url-parameters#answer-371918

This answer claims, that the browser should automatically generate the Authentication header out of the credentials provided in the URL.

When trying it on the command line using curl, it works. So, why doesn't it work in the browser?

Has this something to do with security?

Firefox is the only one claiming:

You are about to log in to the site "localhost" with the username "user", but the website does not require authentication. This may be an attempt to trick you.

Is "localhost" the site you want to visit?

But when confirming this request by clicking on yes, it sends the request without credentials. At least, I can't see them in the network-tab of firebug ... and the response is a 401, too.

回答1:

Yes it is about security, and it is about choice.

First of all, when you use curl to do the operation you mention above, curl defaults to and assumes that you want Basic authentication (unless you specify something else, and yes the name is truly "Basic").

If you ask curl to do HTTP auth with a single method and you provide the credentials, then it decides it can send the auth headers right away. If you instead ask it to do several auth types (which libcurl the underlying library can do), then it won't send any auth header in the first request, but it will instead send a non-auth request to see which methods the server wants - like the browsers do.

In the browsers case, they always have the multiple-auth schemes approach so they don't assume you want Basic auth and by doing so, they don't blindly send your user+password over the network in the clear. They will then only do that if the server actually only wants Basic (or the browser doesn't support whatever more auth types the server supports).

I hope this clarifies things somewhat.