32

I read that "401 Unauthorized" code must be used when a user:

  1. Is not logged, but login is required ("not authenticated");
  2. Is logged, but his profile don't allow to see that url ("not authorized");

According to RFC, in both cases server must return 401 code. But I need to differentiate then in my ajax requests.

Anybody have a tip to solve this?

Note: I don't want to use 403 Forbidden code, because in 403 "Authorization will not help", according to RFC.

0

5 Answers 5

50

Unless you intend to use HTTP authentication, the correct response is 403 ("Forbidden").

A response code of 401 triggers the browser to display a password dialog box, and then resubmit the same request with a Authorization header with the password data that the user supplied. That's probably not the behavior you want.

Don't get too hung up on the explanations in the RFCs -- what you really need to pay attention to are the browser and search engine side effects of the various response codes.

As for the "Authorization will not help" bit, in this case that is correct, since using HTTP authorization (which specifically means the Authorization header), in fact, will not help.

A 403 response tells the browser that the user does not have permission to make that request, and the browser should not attempt to collect authentication data and resubmit the request. That's exactly the response you're after.

Sign up to request clarification or add additional context in comments.

2 Comments

WWW-Authenticate is a response header, not a request header.
@Suleyman oops yep, you're right; it's supposed to be Authorization instead. 13 years and nobody noticed. Corrected.
10

I believe 403 is the right one. We may have to tune the language in the specification to make that clear.

4 Comments

In the spirit of your pettiness, here's the RFC showing that your answer is completely and clearly wrong, by design. It's section 10.4.4
rockerest; first of all RFC 2068 has been obsoleted by RFC 2616 a long time ago. Second, I believe to use 403 is the right choice (see tylerl's answer), and if the text in the spec suggests otherwise, we should consider changing it. Yes, we can.
(the question is now tracked in the HTTPbis Working Group as trac.tools.ietf.org/wg/httpbis/trac/ticket/294)
This is excellent news. This ambiguity in the spec has been confusing me for a while.
3

IIS differentiates these cases with sub-status codes (reference):

  • 401 = User is not logged in, but login is required
  • 401.1 = The user tried to login but their credentials are not valid.
  • 401.3 = The user's credentials are valid but the user is not authorized to see the resource.

3 Comments

Which, IIRC, aren't valid per the HTTP spec: "Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF [...] The Status-Code element is a 3-digit integer result code" (emphasis mine)
I haven't tested it but I guess that IIS only sends 3-digit standard codes in the status line. The substatus is sent in the 'reason phrase', some proprietary header or in the response body only, if it is sent at all.
These differentiated status indicators are used internally by IIS to show a different error page depending on the reason for showing the error.
2

You should pass a custom header in addition to the status code for application specific needs.

I believe the current practice is to preface custom headers with X-

Update, August 2012:

From the RFC 3864 posted in the comments (dated September 2004):

In some cases (notably HTTP [24]), the header syntax and usage is redefined for the specific application. [...] In some cases, the same field name may be specified differently (by different documents) for use with different application protocols. [...] We need to accommodate application-specific fields, while wishing to recognize and promote (where appropriate) commonality of other fields across multiple applications.

In a more recent RFC (6648, dated June 2012), they specifically address X- headers.

Deprecates the "X-" convention for newly defined parameters in application protocols, including new parameters for established protocols. [...] Does not recommend against the practice of private, local, preliminary, experimental, or implementation-specific parameters, only against the use of "X-" and similar constructs in the names of such parameters.

Important to note is that while X- is specifically noted, they do still implicitly condone custom headers as a way of transferring information. An application specific prefix (MyApp-) might be more appropriate to avoid ever colliding with any other headers.

See also: Is it safe to use "X-" header in a HTTP response from a few years ago.

5 Comments

"X-" isn't special in HTTP header fields. See RFC 3864.
Wait, did you seriously downvote me for this? The "Standard" not by definition since, had you read the definition, you would see that defining application specific headers is up to the application designer: there is no standard. It's a "standard" because that's how most people do it, and it's been accepted that X- typically denotes a custom header that the browser can ignore for regular operation.
Just because it's "current practice" doesn't mean it is the right thing to do. There are much better ways to qualify specifically what a HTTP status code means. e.g. Returning a body with details.
A custom header is only meaningful if you also have a custom browser that will interpret it. Otherwise, everything will ignore your custom header and it will have no effect whatsoever.
@tylerl The assumption would be that the custom header is being interpreted either by a server-side application or a client-side application, both of which would be a precursor to even using the custom headers. If you're trying to cause the browser to automatically do something, then you would have to use one of the pre-defined response codes, or use a custom browser as you suggest.
1

This distinction has irritated me for 30 years, and still trips people up. First off, there is a clear distinction between Authentication (AuthN) and Authorization (AuthZ). AuthN is answering the question of "Who are you?" AuthZ answers the question of "What are you allowed to do?" It is necessary to answer the question of AuthN before approaching the question of AuthZ, because you have to know who the user is before deciding what they can do.

"401 Unauthorized" is supposedly stating that the question of AuthN has not been answered, and "403 Forbidden" answers the AuthZ question negatively. What is confusing is that the text "Unauthorized" is incorrect, and has been for 30+ years. Should be "Not Authenticated". But many apps out there are probably looking for the text (instead of just the code), and would break if they changed it now.

Hopefully this clears up the confusing for anyone looking at the response and thinking, "Is that status right?" It is... and it isn't.

Oh, and toss in the "401.3 Unauthorized" for good measure. That one variant has the right text, oddly enough, but is a bit pointless to return, IMHO. I always go with the 403, because the user doesn't need the additional info of what exactly was not authorized. Save that for the logs that the engineer can look over.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.