From 7af2b1db2417ed06ddace6dd8c6bf7c28de85f38 Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Thu, 20 Jul 2023 15:02:34 -0400 Subject: [PATCH] feat!: Add JwtAuthentication as a default DRF auth class. By default DRF sets 'DEFAULT_AUTHENTICATION_CLASSES' to: ``` [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ] ``` We also want to allow for JWT Authentication as a valid default auth choice. This will allow users to send JWT tokens in the authorization header to any existing API endpoints and access them. If any APIs have set custom authentication classes, this will not override that. I believe this is a fairly safe change to make since it only adds one authentication class and does not impact authorization of any of the endpoints that might be affected. Note: This change changes the default for both the LMS and CMS because `cms/envs/common.py` imports this value from the LMS. BREAKING CHANGE: For any affected endpoint that also required the user to be authenticated, the endpoint will now return a 401 in place of a 403 when the user is not authenticated. - See [these DRF docs](https://github.com/encode/django-rest-framework/blob/master/docs/api-guide/authentication.md#unauthorized-and-forbidden-responses) for a deeper explanation about why this changes. - Here is [an example endpoint](https://github.com/openedx/edx-platform/blob/b8ecfed67dc0520b8c4d95de3096b35acc083611/openedx/core/djangoapps/embargo/views.py#L20-L21) that does not override defaults and checks for IsAuthenticated. Generally speaking, this is should not be a problem. An issue would appear only if the caller of the endpoint is specifically handling 403s in a way that would be missed for 401s. --- lms/envs/common.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lms/envs/common.py b/lms/envs/common.py index ac4d9ccd58..de26b10128 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -3332,7 +3332,14 @@ CROSS_DOMAIN_CSRF_COOKIE_NAME = '' REST_FRAMEWORK = { # These default classes add observability around endpoints using defaults, and should # not be used anywhere else. + # Notes on Order: + # 1. `JwtAuthentication` does not check `is_active`, so email validation does not affect it. However, + # `SessionAuthentication` does. These work differently, and order changes in what way, which really stinks. See + # https://github.com/openedx/public-engineering/issues/165 for details. + # 2. `JwtAuthentication` may also update the database based on contents. Since the LMS creates these JWTs, this + # shouldn't have any affect at this time. But it could, when and if another service started creating the JWTs. 'DEFAULT_AUTHENTICATION_CLASSES': [ + 'openedx.core.djangolib.default_auth_classes.DefaultJwtAuthentication', 'openedx.core.djangolib.default_auth_classes.DefaultSessionAuthentication', ], 'DEFAULT_PAGINATION_CLASS': 'edx_rest_framework_extensions.paginators.DefaultPagination',