403 error with Django-Rest-Framework and Django-Oauth-Toolkit in client_credentials mode

654 Views Asked by At

I am trying to us the Django-Oauth-Toolkit authentication with the client_credentials mode, and I can:

  1. create successfully create my client_id and client_secret
  2. register my token

But after, any api call using this token yields a 403 error with the message:

{
    "detail": "You do not have permission to perform this action."
}

My settings.py is:

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "oauth2_provider",
    "rest_framework",
    "drf_yasg",
    "users",
]

MIDDLEWARE = [
    "oauth2_provider.middleware.OAuth2TokenMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]



AUTH_PASSWORD_VALIDATORS = [
    {
        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
    },
    {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",},
    {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",},
    {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",},
]


REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "oauth2_provider.contrib.rest_framework.OAuth2Authentication",
        "rest_framework.authentication.SessionAuthentication",  # To keep the Browsable API
    ),
    "DEFAULT_PERMISSION_CLASSES": (
        "rest_framework.permissions.IsAuthenticated",
        "oauth2_provider.contrib.rest_framework.TokenHasReadWriteScope",
    ),
}

AUTHENTICATION_BACKENDS = (
    "django.contrib.auth.backends.ModelBackend",  # To keep the Browsable API
    "oauth2_provider.backends.OAuth2Backend",
)

1

There are 1 best solutions below

0
Benjamin Breton On BEST ANSWER

Turns out the authentication and permission needed to be specified in the views directly, they are not inherited automatically like with the password mode.

class MyView(APIView):

    authentication_classes = [OAuth2Authentication]
    permission_classes = [TokenHasReadWriteScope]