django-rest-framework/docs/api-guide/permissions.md

128 lines
6.0 KiB
Markdown
Raw Normal View History

2012-09-09 01:06:13 +04:00
<a class="github" href="permissions.py"></a>
2012-09-05 13:01:43 +04:00
2012-09-12 13:12:13 +04:00
# Permissions
> Authentication or identification by itself is not usually sufficient to gain access to information or code. For that, the entity requesting access must have authorization.
>
> &mdash; [Apple Developer Documentation][cite]
2012-10-21 18:34:07 +04:00
Together with [authentication] and [throttling], permissions determine whether a request should be granted or denied access.
2012-09-12 13:12:13 +04:00
Permission checks are always run at the very start of the view, before any other code is allowed to proceed. Permission checks will typically use the authentication information in the `request.user` and `request.auth` properties to determine if the incoming request should be permitted.
## How permissions are determined
2012-09-13 12:39:16 +04:00
Permissions in REST framework are always defined as a list of permission classes.
2012-09-12 13:12:13 +04:00
2012-09-13 12:39:16 +04:00
Before running the main body of the view each permission in the list is checked.
2012-09-12 13:12:13 +04:00
If any permission check fails an `exceptions.PermissionDenied` exception will be raised, and the main body of the view will not run.
## Object level permissions
REST framework permissions also support object-level permissioning. Object level permissions are used to determine if a user should be allowed to act on a particular object, which will typically be a model instance.
Object level permissions are run by REST framework's generic views when `.get_object()` is called. As with view level permissions, an `exceptions.PermissionDenied` exception will be raised if the user is not allowed to act on the given object.
## Setting the permission policy
The default permission policy may be set globally, using the `DEFAULT_PERMISSION_CLASSES` setting. For example.
2012-09-12 13:12:13 +04:00
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
2012-09-12 13:12:13 +04:00
)
}
2012-10-27 23:04:33 +04:00
If not specified, this setting defaults to allowing unrestricted access:
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
)
2012-09-12 13:12:13 +04:00
You can also set the authentication policy on a per-view basis, using the `APIView` class based views.
class ExampleView(APIView):
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
Or, if you're using the `@api_view` decorator with function based views.
@api_view('GET')
@permission_classes((IsAuthenticated, ))
2012-09-12 13:12:13 +04:00
def example_view(request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
2012-10-17 18:41:57 +04:00
---
2012-10-15 16:27:50 +04:00
# API Reference
2012-10-27 23:04:33 +04:00
## AllowAny
The `AllowAny` permission class will allow unrestricted access, **regardless of if the request was authenticated or unauthenticated**.
This permission is not strictly required, since you can achieve the same result by using an empty list or tuple for the permissions setting, but you may find it useful to specify this class because it makes the intention explicit.
2012-09-12 13:12:13 +04:00
## IsAuthenticated
The `IsAuthenticated` permission class will deny permission to any unauthenticated user, and allow permission otherwise.
This permission is suitable if you want your API to only be accessible to registered users.
## IsAdminUser
2012-10-29 12:23:25 +04:00
The `IsAdminUser` permission class will deny permission to any user, unless `user.is_staff` is `True` in which case permission will be allowed.
2012-09-12 13:12:13 +04:00
This permission is suitable is you want your API to only be accessible to a subset of trusted administrators.
## IsAuthenticatedOrReadOnly
The `IsAuthenticatedOrReadOnly` will allow authenticated users to perform any request. Requests for unauthorised users will only be permitted if the request method is one of the "safe" methods; `GET`, `HEAD` or `OPTIONS`.
This permission is suitable if you want to your API to allow read permissions to anonymous users, and only allow write permissions to authenticated users.
## DjangoModelPermissions
2012-09-12 16:11:26 +04:00
This permission class ties into Django's standard `django.contrib.auth` [model permissions][contribauth]. When applied to a view that has a `.model` property, authorization will only be granted if the user has the relevant model permissions assigned.
* `POST` requests require the user to have the `add` permission on the model.
* `PUT` and `PATCH` requests require the user to have the `change` permission on the model.
* `DELETE` requests require the user to have the `delete` permission on the model.
The default behaviour can also be overridden to support custom model permissions. For example, you might want to include a `view` model permission for `GET` requests.
To use custom model permissions, override `DjangoModelPermissions` and set the `.perms_map` property. Refer to the source code for details.
2012-09-12 23:39:22 +04:00
The `DjangoModelPermissions` class also supports object-level permissions. Third-party authorization backends such as [django-guardian][guardian] that provide object-level permissions should work just fine with `DjangoModelPermissions` without any custom configuration required.
2012-09-12 13:12:13 +04:00
2012-10-17 18:41:57 +04:00
---
2012-10-15 16:27:50 +04:00
# Custom permissions
2012-09-12 13:12:13 +04:00
To implement a custom permission, override `BasePermission` and implement the `.has_permission(self, request, view, obj=None)` method.
2012-09-12 13:12:13 +04:00
The method should return `True` if the request should be granted access, and `False` otherwise.
## Example
The following is an example of a permission class that checks the incoming request's IP address against a blacklist, and denies the request if the IP has been blacklisted.
class BlacklistPermission(permissions.BasePermission):
def has_permission(self, request, view, obj=None):
ip_addr = request.META['REMOTE_ADDR']
blacklisted = Blacklist.objects.filter(ip_addr=ip_addr).exists()
return not blacklisted
2012-10-17 18:41:57 +04:00
2012-09-12 13:12:13 +04:00
[cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html
[authentication]: authentication.md
2012-09-12 16:11:26 +04:00
[throttling]: throttling.md
[contribauth]: https://docs.djangoproject.com/en/1.0/topics/auth/#permissions
[guardian]: https://github.com/lukaszb/django-guardian