9

I'm using Django 2.0 and Django RESET Framework to write REST API for my application.

I have configured following authentication methods

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
}

As of now, It allows all authenticated users to access web api view.

What I want is to allow few users (probably superadmin users) to be able to access API from Session Authentication or from web browser by logging in.

Edit 2: contacts/views.py

class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = (IsAuthenticated,)

    def perform_create(self, serializer):
        serializer.save(user_id=self.request.user)
6
  • Can you add your contacts API view? Commented May 14, 2018 at 15:05
  • updated code in question Commented May 14, 2018 at 15:07
  • And you are sure that the browser request is using an authenticated user? Commented May 14, 2018 at 15:15
  • Got it, my configuration was misconfigured a little. But how to restrict web access to superadmin users only? Commented May 14, 2018 at 15:16
  • You'd have to create a custom middleware or build that into your views. There shouldn't be any reason to limit a valid user to the same features based upon how their accessing the system. Commented May 14, 2018 at 15:19

3 Answers 3

15

For Django 2 (Added in views.py)

from rest_framework.permissions import IsAdminUser

class IsSuperUser(IsAdminUser):
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_superuser)

class ListSmth(ListCreateAPIView):
    permission_classes = (IsSuperUser,)
    ... Your code...
Sign up to request clarification or add additional context in comments.

1 Comment

It would be better to inherit from rest_framework.permissions.BasePermission rather than rest_framework.permissions.IsAdminUser
5

There is already inbuilt class called IsAdminUser, specify it as values to permission_classes property

from rest_framework.permissions import IsAdminUser

class A:
    permission_classes = (IsAdminUser,)

this checks for the value

reques.user.is_staff == True

1 Comment

Note that (as you said) this checks for is_staff but the question specified super users.
3

So you can leverage permission_classes to do this. DRF's Request object remembers the authentication method that was used in an attribute called _authenticator. You can use this; and use the permission_classes to determine if the pair of (user, authenticator) has permission

class AdminAuthenticationPermission(permissions.BasePermission):
    ADMIN_ONLY_AUTH_CLASSES = [rest_framework.authentication.BasicAuthentication, rest_framework.authentication.SessionAuthentication]

    def has_permission(self, request, view):
        user = request.user
        if user and user.is_authenticated():
            return user.is_superuser or \
                not any(isinstance(request._authenticator, x) for x in self.ADMIN_ONLY_AUTH_CLASSES) 
        return False

class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = (IsAuthenticated, AdminAuthenticationPermission,)

Untested: but should work

5 Comments

great it's working. only little modification is required. remove () from is_authenticated(). rest is good
Great to hear! That's a change in Django 1.10 I think; I am more used to 1.9 Old habits docs.djangoproject.com/en/2.0/releases/1.10/…
Yes, I had used the same thing in version earlier to 1.10. But it will return TypeError: 'bool' object is not callable on 2.0
I'd recommend updating your question to reflect the real underlying question and the corresponding answer for better future reference.
Remove () from end of user.is_authenticated() to fix TypeError @AnujTBE

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.