2

I'm creating an API using Django rest framework and I'm adding oauth2 authentication. I was able to set it up correctly and I can get the token to access my API end points. So far everything good.

My question now is how to be a bit more selective in what is protected and what is public. In my API there is a subset of end points that can be accessed by everybody so that they are anonymous users and they can't get the access token in the same way because username and password doesn't exists.

Here is the related content in my settings.py:

OAUTH2_PROVIDER = {
    # this is the list of available scopes
    'SCOPES': {
        'read': 'Read scope',
        'write': 'Write scope',
        'groups': 'Access to your groups'
    }
}

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'oauth2_provider.ext.rest_framework.OAuth2Authentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAdminUser',
    ),
    'PAGE_SIZE': 10
}
INSTALLED_APPS = (
    ...
    'oauth2_provider',
    'rest_framework',
    ...
)

views.py:

# Everything fine for this end point
class PrivateViewSet(viewsets.ModelViewSet):
    serializer_class = custom_serializers.MySerializer
    http_method_names = ['get', 'post', 'head', 'options']
    permission_classes = (permissions.IsAuthenticated, custom_permissions.IsAdminOrOwner, TokenHasReadWriteScope)

# Getting the error
class PublicViewSet(viewsets.ModelViewSet):
    serializer_class = custom_serializers.MyPublicSerializer
    permission_classes = (permissions.AllowAny,)

So when I try to access to "PublicViewSet" end point I get the following error:

{"detail": "Authentication credentials were not provided."}

Is there a way to decide to which end points to apply the oauth2 authorization and keep others open publicly?

1 Answer 1

1

You are not been able to access the PublicViewSet endpoint because it is looking for the token in the setting you provided the DEFAULT_AUTHENTICATION_CLASSES. It follows the classes. To avoid this in the view you need to pass an empty authentication_classes.

class PublicViewSet(viewsets.ModelViewSet):
    serializer_class = custom_serializers.MyPublicSerializer
    authentication_classes = ()
    permission_classes = (permissions.AllowAny,)
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for you reply. I also found a workaround to have more than one authentication class by default by adding it like this in the settings.py 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.BasicAuthentication', 'oauth2_provider.ext.rest_framework.OAuth2Authentication', ), Then in combination with the permission_classes I could get it working.

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.