Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
165 views
in Technique[技术] by (71.8m points)

Could not setup django-oauth-toolkit authentication

I'm going to restrict my working rest_framework.views.APIView inherited class, to be visible only by authenticated users.
I made these modifications:

  1. Added authentication_classes and permission_classes to my class:
class TestView(APIView):
    authentication_classes = (OAuth2Authentication,)
    permission_classes = (IsAuthenticated,)

    return Response("Hey there...")
  1. Got an access_token from django-oauth-toolkit:
curl -XPOST "http://172.18.0.1:8000/oauth2/token/" 
-d 'grant_type=client_credentials&client_id=MY-CLIENT-ID&client_secret=MY-CLIENT-SECRET'
{"access_token": "Haje1ZTrc7VH4rRkTbJCIkX5u83Tm6", "expires_in": 36000, "token_type": "Bearer", "scope": "read write groups"}
  1. Tried requesting the view without setting the access_token:
curl -XGET "http://172.18.0.1:8000/api/v1/test/"
{"detail":"Authentication credentials were not provided."}
  1. Tried a new request with the access_token:
curl -XGET "http://172.18.0.1:8000/api/v1/test/" 
-H "Authorization: Bearer Haje1ZTrc7VH4rRkTbJCIkX5u83Tm6"
{"detail":"You do not have permission to perform this action."}

Should I do anything more to enable access_token authentication?

Note: I have installed these libraries in the environment:

Django==2.2.17
djangorestframework==3.12.2
django-oauth-toolkit==1.3.3

Note2: Forgot to say that rest_framework and oauth2_provider have been added to INSTALLED_APPS.

IMPORTANT EDIT:
This problem exists only if using "client credential grant" for authentication. check my own answer below.

question from:https://stackoverflow.com/questions/65645104/could-not-setup-django-oauth-toolkit-authentication

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In the end I found that OAuth2Authentication does not authenticate a user by its client_credential (accepts username/password pair with grant_type=password). so I wrote this custom authenticator. hope it helps other guys with the same problem.

from oauth2_provider.contrib.rest_framework import OAuth2Authentication
from oauth2_provider.models import Application


class OAuth2ClientCredentialAuthentication(OAuth2Authentication):
    """
    OAuth2Authentication doesn't allows credentials to belong to an application (client).
    This override authenticates server-to-server requests, using client_credential authentication.
    """
    def authenticate(self, request):
        authentication = super().authenticate(request)

        if not authentication is None:
            user, access_token = authentication
            if self._grant_type_is_client_credentials(access_token):
                authentication = access_token.application.user, access_token

        return authentication

    def _grant_type_is_client_credentials(self, access_token):
        return access_token.application.authorization_grant_type == Application.GRANT_CLIENT_CREDENTIALS

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...