403 Forbidden: The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
Now, in our case we decide that we don’t want to reveal that indeed the resource is available to anyone who doesn’t have access. It doesn’t have to be the Glimpse.axd resource as in our example, it simply might be some resource that we want to be available to only those who are authorized. But for those less fortunate to have access, we want to make it less conspicuous. It’s also apparent that this was a foreseen need when you read that last sentence of the 403 definition: “if the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead”. For reference, “this information” refers to the information on why the request was not fulfilled.
In order to have a working solution we need to meet the following criteria:
Return a custom error, specifically one that conveys the requested resource does not exists
Clearly return a complementing 404 HTTP status code to back up the custom error instead of the 403
Retain normal 404 behavior"