1
votes

How does an HTTP client definitively determine whether a login was successful when using Basic Authentication? I've always thought that it was simple - look at the response code:

  • 200 = Successful
  • 401 = Unsuccessful

This is not correct. If you read RFC 2617 it says:

If the origin server does not wish to accept the credentials sent with a request, it SHOULD return a 401 (Unauthorized) response. The response MUST include a WWW-Authenticate header field containing at least one (possibly new) challenge applicable to the requested resource.

The word SHOULD is tricky, and in fact I've seen devices that do not return a 401 on login failure. This would suggest:

  • WWW-Authenticate does not exist = Successful
  • WWW-Authenticate exists = Unsuccessful

This is also incorrect. I'm playing with a TP-LINK router that provides the following headers:

  - Server : Router Webserver
  - Connection : close
  - Content-Type : text/html
  - WWW-Authenticate : Basic realm="TP-LINK Wireless N Router WR841N"

The response code is 200.

Here we have a 200 with a WWW-Authenticate!!!!!

Given all of this, what is the DEFINITIVE way to determine whether a BA login was successful?

2
The response code is the most reliable way. If the server sends the wrong response code then the server is not playing nice. Nothing you can do about that.Remy Lebeau
Okay, so a server could respond any way that it wanted, even if it is against the spec. But given this spec, what is the "correct" way to determine that the login was a success?Sander Smith
As I said, the response code is the "correct" way. However, the spec also says: "HTTP does not restrict applications to this simple challenge-response framework for access authentication. Additional mechanisms can be used, such as authentication at the transport level or via message encapsulation, and with additional header fields specifying authentication information. However, such additional mechanisms are not defined by this specification.", which is why SHOULD is used instead of MUST, I think.Remy Lebeau

2 Answers

2
votes

RFC 7235 obsoletes RFC 2617 and one of the corrections it brings is to point out that, SHOULD is to be interpreted as per RFC 2119. (This was perhaps omitted because it is pointed out in RFC 2616, which goes hand-in-hand with 2617):

SHOULD This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

So, it's not just a matter of "well, you should do that, but we understand if you don't" as should means colloquially, but rather "you must do this, unless you have an extremely good reason that you can clearly state".

If a server has a very good reason for not sending a 401, it's most likely because it is sending some other error code (e.g. 404 to pretend the resource doesn't exist unless you've successfully authenticated). The wisdom of sending anything other than 401 is perhaps questionable, but the only reason to send 200 is because you want to indicate that the response is successful. Really, while the should does allow something other than 401, it really doesn't allow 200.

Including WWW-Authenticate on the other hand, definitely doesn't mean the authentication wasn't successful. It's allowed at any time, and with other schemes apart from Basic can be necessary on successful requests (to allow a nonce-count to increment, for example).

In short you've got three possible states: Success, Authentication Error, Some Other Error. The should allows for the last of those. If you get a 200 then you were successful (or well, the server is behaving wrong, but that always applies anyway).

0
votes

The 200 status is what counts. That the server keeps including WWW-Authenticate simply is a bug.

And yes, I tested this, I happen to have the same router over here.