Correct HTTP status code when resource is available but not accessible because of permissions

22,302

Solution 1

According to Wikipedia (and RFC 2616), a 401 code is used when a page exists but requires authentication; 403 is for a page where authenticating won't change anything. (In the wild, 403 usually means the permissions on something are wrong, whereas a 401 will prompt the user for a username/password). 404 is for where the document simply doesn't exist.

In your case, it seems like 401 is the most appropriate code, since there is some way of authenticating the users who DO have access to the page.

Solution 2

Definitely NOT 404. 404 is just Not Found.
401 is access denied.
403 is forbidden.

I would go with 401

Solution 3

If authorization credentials are provided in the request and the requester does not have permissions to access this resource then you should return 403.

If no authorization credentials are provided in the request then you should return 401.

Solution 4

To me I will use 400 Bad request.
Because my application will not go unaccessable resources in programmatically.
Filtering users permission and hide unaccessable resources is good user experience in my opinion. If my server got unaccessable request which means some person trying to do something.
That is why I choose 400 - Bad request in my applications.

Share:
22,302
Admin
Author by

Admin

Updated on July 22, 2022

Comments

  • Admin
    Admin almost 2 years

    I am building a RESTful protocol for Dynamic Carpooling applications, for my Computer Science thesis.

    In the Protocol I also have to formally specify the HTTP status code for each operation. I've got this "privacy related" problem. Suppose the following:

    GET /api/persons/angela/location

    Retrieves the current position of user "angela". It is obvious that not everybody should be able to obtain a result. Only angela itself and a possible driver that is going to pick her should be able to know it.

    I can not decide whether to return a 404 Not Found or a 401 Forbidden here.

    Any hints? What would be the best one and why?

  • Admin
    Admin over 13 years
    Good one! Quite the whole protocol operations require authentications. I've got cases in which resources are available but cannot be retrieved because of user rights and also cases in which resources are not available because the were previously deleted. Both cases are under authenticated operations. Would you go for a 401 in the first case and a 404 for the second case? Therefore: resource exists but you can not access it -> 401 resource does not exist -> 404
  • Phil
    Phil over 13 years
    Yes, if a resource was deleted, a 404 is appropriate if an attempt is subsequently made to access it.
  • Day
    Day over 13 years
    If authorization credentials are provided in the request and the requester does not have permissions to access this resource then you should return 401 not a 403. RFC 2616 explicitly says that for a 403, "Authorization will not help and the request SHOULD NOT be repeated" (tools.ietf.org/html/rfc2616#section-10.4.4). So if there are valid credentials that would give permission to access the resource, don't return a 403.
  • Day
    Day over 13 years
    Good answer, but I'd prefer "according to Wikipedia" to say "according to RFC 2616" tools.ietf.org/html/rfc2616#section-10.4.2 ;)
  • Darrel Miller
    Darrel Miller over 13 years
    @Day You are absolutely correct. My answer is wrong. Hmm, you learn something new every day.
  • Day
    Day over 13 years
    No worries. How about having a stab at my spin off question stackoverflow.com/q/4038981/445073 :)
  • Eric Stein
    Eric Stein almost 10 years
    401 is not access denied. It is "not logged in and login required".
  • Parth Shah
    Parth Shah almost 9 years
    @EricStein According to RFC 2616 (tools.ietf.org/html/rfc2616#section-10.4.2), "If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials." So 401 is in fact access denied.
  • Mikkel Løkke
    Mikkel Løkke over 7 years
    I disagree. responding with a 400 Bad Request for valid requests is a broken API. 400 Bad Request means that something is wrong with the request. Anyone using your API will think the request is wrong, when in reality, the request is right, this is literally what 401 and 403 are for. It makes things easier to debug.
  • jeefo
    jeefo over 7 years
    As I said normal users never request unaccessable resources. If my server got unaccessable request which means some sneaky person trying to hack unaccessable resources. Also I will never respond error code for valid requests.
  • Mikkel Løkke
    Mikkel Løkke over 7 years
    You should generally never make assumptions about what normal users will and won't do. Authentication is not necessarily part of the request. If you're worried about sneaky people, the correct solution is not intentionally breaking the HTTP (security by obscurity). The correct solution is to put up a firewall in front of your API, so that the sneaky people can't even probe your API in the first place.
  • jeefo
    jeefo over 7 years
    I never said anything about Authentication. There are many different departments and many different users role in my application. Because my client is very big corporation. In my application lots of private data here. Because of that every user is thread to me. Who knows their computer hacked or not... In front end application is never access unaccessable resources in programmatically. So in server side I will validate every request by user, make sure it is valid request. If is not stop executing and respond 400.
  • Jithin Jose
    Jithin Jose over 5 years
    But, giving 401 response exposes the fact that file actually exists.
  • StackOverflowUser
    StackOverflowUser over 2 years
    In my scenario a certain sort of db resource is available whether or not the requester is logged-in. BUT that resource can be set, in terms of that website, as 'Private' or 'Public'. Authorization credentials are irrelevant in this scenario; the non-standard status of "It's set Private" is the determiner, so I believe the appropriate status to send back in this scenario is HTTP 403 / Forbidden.