Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API authentication: Default failed authentication should return 403 not 401 #117

rwillmer opened this Issue Apr 8, 2011 · 4 comments


None yet
6 participants
Copy link

rwillmer commented Apr 8, 2011

From my understanding of the HTTP RFC, returning a 401 expects the client to respond with a WWW-Authenticate header and new credentials.

Whereas if the user has provided an invalid API key or is over the limit, 403 Forbidden looks more appropriate.

Just a thought...


This comment has been minimized.

Copy link

gingerlime commented Aug 28, 2011

I just came across the same thing, but there's a way around it. If you look at the code that checks the is_authorized response, it actually allows either a True/False, or a HttpResponse

So a simple way to raise the correct response is to build an 403 HttpResponse object

def Http403():
    response = render_to_response("403.html")
    response.status_code = 403
    return response

and then call it in your is_authorized, like this:

def is_authorized(self, request, object=None):
        if request and hasattr(request, 'user'):
            # blocking john
            if == 'john':
                return Http403()

I still think it would be better if tastypie did it automatically. 403 is definitely the more correct response if the request is not authorized (rather than not authenticated).


This comment has been minimized.

Copy link

jleclanche commented Apr 26, 2013

Tastypie's current behaviour is indeed broken; it shouldn't be returning a 401 without a WWW-Authenticate header.

The other authentication methods oblige to this behaviour. Simple fix is to add a WWW-Authenticate = "apikey" header to the response in ApiKeyAuthentication._unauthorized().

Example app-level fix:

from tastypie.authentication import ApiKeyAuthentication as _ApiKeyAuthentication
from tastypie.http import HttpUnauthorized

class ApiKeyAuthentication(_ApiKeyAuthentication):
       def _unauthorized(self):
               response = HttpUnauthorized()
               response["WWW-Authenticate"] = "apikey"
               return response

This comment has been minimized.

Copy link

istodi commented Aug 29, 2013

Based on what @adys did, I make a little change only changing the status_code of the response to 403.

from tastypie.authentication import BasicAuthentication as _BasicAuthentication

class BasicAuthentication(_BasicAuthentication):
    def _unauthorized(self):
        response = super(BasicAuthentication, self)._unauthorized()
        response.status_code = 403
        return response

@georgedorn georgedorn added wontfix easy_to_fix and removed wontfix labels Apr 9, 2015


This comment has been minimized.

Copy link

georgedorn commented Apr 9, 2015

Marking easy_to_fix because combining @gingerlime's suggestions with a test case would make for a readily-accepted PR.

@SeanHayes SeanHayes added this to the v0.13.0 milestone Oct 12, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.