Categories
http-headers http-response-codes http-status-code-401 http-status-code-403 http-status-codes

403 Forbidden vs 401 Unauthorized HTTP responses

3359

For a web page that exists, but for which a user does not have sufficient privileges (they are not logged in or do not belong to the proper user group), what is the proper HTTP response to serve?

401 Unauthorized?
403 Forbidden?
Something else?

What I’ve read on each so far isn’t very clear on the difference between the two. What use cases are appropriate for each response?

9

  • 561

    401 ‘Unauthorized’ should be 401 ‘Unauthenticated’, problem solved !

    May 17, 2016 at 12:33

  • 86

    I don’t remember how many times me and my colleagues have come back to stackoverflow for this question. Maybe HTTP standards should consider modifying the names or descriptions for 401 and 403.

    – neurite

    Feb 4, 2017 at 1:14


  • 3

    @Qwerty no, the new RFC7231 obsoletes RFC2616. 403 has a different meaning now.

    – fishbone

    Aug 1, 2018 at 13:15

  • 2

    @fishbone you also did not note that status code 401 has been removed from that RFC 😀

    Nov 22, 2018 at 12:06

  • 1

    @fishbone it’s been added back to that proposal now but uses a different RFC now 7235 tools.ietf.org/html/rfc7235#section-3.1

    Jan 16, 2020 at 15:24

4834

A clear explanation from Daniel Irvine [original link]:

There’s a problem with 401 Unauthorized, the HTTP status code for authentication errors. And that’s just it: it’s for authentication, not authorization.
Receiving a 401 response is the server telling you, “you aren’t
authenticated–either not authenticated at all or authenticated
incorrectly–but please reauthenticate and try again.” To help you out,
it will always include a WWW-Authenticate header that describes how
to authenticate.

This is a response generally returned by your web server, not your web
application.

It’s also something very temporary; the server is asking you to try
again.

So, for authorization I use the 403 Forbidden response. It’s
permanent, it’s tied to my application logic, and it’s a more concrete
response than a 401.

Receiving a 403 response is the server telling you, “I’m sorry. I know
who you are–I believe who you say you are–but you just don’t have
permission to access this resource. Maybe if you ask the system
administrator nicely, you’ll get permission. But please don’t bother
me again until your predicament changes.”

In summary, a 401 Unauthorized response should be used for missing
or bad authentication, and a 403 Forbidden response should be used
afterwards, when the user is authenticated but isn’t authorized to
perform the requested operation on the given resource.

Another nice pictorial format of how http status codes should be used.

22

  • 53

    The default IIS 403 message is “This is a generic 403 error and means the authenticated user is not authorized to view the page”, which would seem to agree.

    Sep 16, 2011 at 13:19

  • 404

    @JPReddy Your answer is correct. However, I would expect that 401 to be named “Unauthenticated” and 403 to be named “Unauthorized”. It is very confusing that 401, which has to do with Authentication, has the format accompanying text “Unauthorized”….Unless I am not good in English (which is quite a possibility).

    Jun 20, 2012 at 21:48

  • 69

    @ZaidMasud, according to RFC this interpretation is not correct. Cumbayah’s answer got it right. 401 means “you’re missing the right authorization”. It implies “if you want you might try to authenticate yourself”. So both a client who didn’t authenticate itself correctly and a properly authenticated client missing the authorization will get a 401. 403 means “I won’t answer to this, whoever you are”. RFC states clearly thath “authorization will not help” in the case of 403.

    – Davide R.

    Nov 24, 2012 at 10:38

  • 99

    401 is Authentication error, 403 is Authorization error. Simple as that.

    Mar 25, 2013 at 14:09

  • 44

    To all downvoters referring to an RFC (most likely 2616), you are all wrong. As specified in the answer by @Idrut, “Forbidden means that the client has authenticated successfully, but is not authorized.”. He references RFC7231 and RFC7235 which obsolete RFC 2616.

    – Tom Lint

    Sep 22, 2015 at 8:43


484

Edit: RFC2616 is obsolete, see RFC7231 and RFC7235.

401 Unauthorized:

If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials.

403 Forbidden:

The server understood the request, but is refusing to fulfill it.

From your use case, it appears that the user is not authenticated. I would return 401.


11

  • 25

    Thanks, that helped clarify it for me. I’m using both – the 401 for unauthenticated users, the 403 for authenticated users with insufficient permissions.

    Jul 21, 2010 at 7:51

  • 52

    I didn’t downvote but I find this answer quite misleading. 403 forbidden is more appropriately used in content that will never be served (like .config files in asp.net). its either that or a 404. imho, it wouldn’t be appropriate to return 403 for something that can be accessed but you just didn’t have the right credentials. my solution would be to give an access denied message with a way to change credentials. that or a 401.

    – Mel

    Dec 22, 2011 at 5:07

  • 30

    “The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource.” It would seem that if you don’t want to use HTTP-style authentication, a 401 response code is not appropriate.

    – Brilliand

    Mar 20, 2012 at 1:42

  • 9

    I’ll back Billiand here. The statement is “If the request already included Authorization credentials”. That means if this is a response from a request which provided the credential (e.g. the response from a RFC2617 Authentication attempt). It is essentially to allow the server to say, “Bad account/password pair, try again”. In the posed question, the user is presumably authenticated but not authorized. 401 is never the appropriate response for those circumstances.

    – ldrut

    Feb 5, 2013 at 17:20

  • 8

    Brilliand is right, 401 is only appropriate for HTTP Authentication.

    May 3, 2013 at 15:42

327

Something the other answers are missing is that it must be understood that Authentication and Authorization in the context of RFC 2616 refers ONLY to the HTTP Authentication protocol of RFC 2617. Authentication by schemes outside of RFC2617 is not supported in HTTP status codes and are not considered when deciding whether to use 401 or 403.

Brief and Terse

Unauthorized indicates that the client is not RFC2617 authenticated and the server is initiating the authentication process. Forbidden indicates either that the client is RFC2617 authenticated and does not have authorization or that the server does not support RFC2617 for the requested resource.

Meaning if you have your own roll-your-own login process and never use HTTP Authentication, 403 is always the proper response and 401 should never be used.

Detailed and In-Depth

From RFC2616

10.4.2 401 Unauthorized

The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8).

and

10.4.4 403 Forbidden
The server understood the request but is refusing to fulfil it. Authorization will not help and the request SHOULD NOT be repeated.

The first thing to keep in mind is that “Authentication” and “Authorization” in the context of this document refer specifically to the HTTP Authentication protocols from RFC 2617. They do not refer to any roll-your-own authentication protocols you may have created using login pages, etc. I will use “login” to refer to authentication and authorization by methods other than RFC2617

So the real difference is not what the problem is or even if there is a solution. The difference is what the server expects the client to do next.

401 indicates that the resource can not be provided, but the server is REQUESTING that the client log in through HTTP Authentication and has sent reply headers to initiate the process. Possibly there are authorizations that will permit access to the resource, possibly there are not, but let’s give it a try and see what happens.

403 indicates that the resource can not be provided and there is, for the current user, no way to solve this through RFC2617 and no point in trying. This may be because it is known that no level of authentication is sufficient (for instance because of an IP blacklist), but it may be because the user is already authenticated and does not have authority. The RFC2617 model is one-user, one-credentials so the case where the user may have a second set of credentials that could be authorized may be ignored. It neither suggests nor implies that some sort of login page or other non-RFC2617 authentication protocol may or may not help – that is outside the RFC2616 standards and definition.


Edit: RFC2616 is obsolete, see RFC7231 and RFC7235.

7

  • 7

    So what should we do when the user requests a page that requires non-http authentication? Send status code 403?

    Mar 25, 2014 at 11:00


  • 12

    This is important: “if you have your own roll-your-own login process and never use HTTP Authentication, 403 is always the proper response and 401 should never be used.”

    – ggg

    Dec 31, 2014 at 6:25

  • 1

    @marcovtwout Send a 302 to your login-page, or a 403 containing a body with information how to log in?

    – Alex

    Feb 2, 2015 at 11:38

  • 3

    RFC2616 should be burned and replaced by RFC7235, but contains no changes in this topic as far as I can see.

    – Alex

    Feb 3, 2015 at 5:57


  • 7

    Doesn’t RFC7235 provide for “roll-your-own” or alternate auth challenges? Why can’t my app’s login flow present its challenge in the form of a WWW-Authenticate header? Even if a browser doesn’t support it, my React app can…

    – jchook

    Oct 11, 2016 at 15:53