Use two seperate exceptions - AuthenticationFailed, and NotAuthenticated

Cleaner seperation of exception and resulting HTTP response.
Should result in more obvious error messages.
This commit is contained in:
Tom Christie 2012-10-17 15:23:36 +01:00
parent a4d500ba10
commit b78872b7db
3 changed files with 24 additions and 8 deletions

View File

@ -156,12 +156,12 @@ Unauthenticated responses that are denied permission will result in an `HTTP 403
To implement a custom authentication scheme, subclass `BaseAuthentication` and override the `.authenticate(self, request)` method. The method should return a two-tuple of `(user, auth)` if authentication succeeds, or `None` otherwise.
In some circumstances instead of returning `None`, you may want to raise an `Unauthenticated` exception from the `.authenticate()` method.
In some circumstances instead of returning `None`, you may want to raise an `AuthenticationFailed` exception from the `.authenticate()` method.
Typically the approach you should take is:
* If authentication is not attempted, return `None`. Any other authentication schemes also in use will still be checked.
* If authentication is attempted but fails, raise an `Unauthenticated` exception. An error response will be returned immediately, without checking any other authentication schemes.
* If authentication is attempted but fails, raise a `AuthenticationFailed` exception. An error response will be returned immediately, without checking any other authentication schemes.
You *may* also override the `.authentication_header(self, request)` method. If implemented, it should return a string that will be used as the value of the `WWW-Authenticate` header in a `HTTP 401 Unauthorized` response.

View File

@ -49,11 +49,19 @@ Raised if the request contains malformed data when accessing `request.DATA` or `
By default this exception results in a response with the HTTP status code "400 Bad Request".
## Unauthenticated
## AuthenticationFailed
**Signature:** `Unauthenticated(detail=None)`
**Signature:** `AuthenticationFailed(detail=None)`
Raised when an unauthenticated incoming request fails the permission checks.
Raised when an incoming request includes incorrect authentication.
By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the [authentication documentation][authentication] for more details.
## NotAuthenticated
**Signature:** `NotAuthenticated(detail=None)`
Raised when an unauthenticated request fails the permission checks.
By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the [authentication documentation][authentication] for more details.
@ -61,7 +69,7 @@ By default this exception results in a response with the HTTP status code "401 U
**Signature:** `PermissionDenied(detail=None)`
Raised when an authenticated incoming request fails the permission checks.
Raised when an authenticated request fails the permission checks.
By default this exception results in a response with the HTTP status code "403 Forbidden".

View File

@ -23,9 +23,17 @@ class ParseError(APIException):
self.detail = detail or self.default_detail
class Unauthenticated(APIException):
class AuthenticationFailed(APIException):
status_code = status.HTTP_401_UNAUTHORIZED
default_detail = 'Incorrect or absent authentication credentials.'
default_detail = 'Incorrect authentication credentials.'
def __init__(self, detail=None):
self.detail = detail or self.default_detail
class NotAuthenticated(APIException):
status_code = status.HTTP_401_UNAUTHORIZED
default_detail = 'Authentication credentials were not provided.'
def __init__(self, detail=None):
self.detail = detail or self.default_detail