From f1a2b7c60354b2aa20c0468687a97ab0741081d1 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Mon, 29 Jul 2024 15:52:19 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(backend)=20authenticate=20requests=20?= =?UTF-8?q?using=20an=20access=20token=20issued=20by=20AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Overload mozilla-django-oidc class to support an authentication method with the resource server backend. This enables any route of the API to be called with an access token issued by Agent Connect. --- .../core/resource_server/authentication.py | 49 +++++++++++++++++++ src/backend/people/settings.py | 1 + 2 files changed, 50 insertions(+) create mode 100644 src/backend/core/resource_server/authentication.py diff --git a/src/backend/core/resource_server/authentication.py b/src/backend/core/resource_server/authentication.py new file mode 100644 index 0000000..7be60e5 --- /dev/null +++ b/src/backend/core/resource_server/authentication.py @@ -0,0 +1,49 @@ +"""Resource Server Authentication""" + +import base64 +import binascii +import logging + +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured + +from mozilla_django_oidc.contrib.drf import OIDCAuthentication + +from .backend import ResourceServerBackend +from .clients import AuthorizationServerClient + +logger = logging.getLogger(__name__) + + +class ResourceServerAuthentication(OIDCAuthentication): + """Authenticate clients using the token received from the authorization server.""" + + def __init__(self): + super().__init__() + + authorization_server_client = AuthorizationServerClient( + url=settings.OIDC_OP_URL, + verify_ssl=settings.OIDC_VERIFY_SSL, + timeout=settings.OIDC_TIMEOUT, + proxy=settings.OIDC_PROXY, + url_jwks=settings.OIDC_OP_JWKS_ENDPOINT, + url_introspection=settings.OIDC_OP_INTROSPECTION_ENDPOINT, + ) + + self.backend = ResourceServerBackend(authorization_server_client) + + def get_access_token(self, request): + """Retrieve and decode the access token from the request. + + This method overcharges the 'get_access_token' method from the parent class, + to support service providers that would base64 encode the bearer token. + """ + + access_token = super().get_access_token(request) + + try: + access_token = base64.b64decode(access_token).decode("utf-8") + except (binascii.Error, TypeError): + pass + + return access_token diff --git a/src/backend/people/settings.py b/src/backend/people/settings.py index 9c22936..f28997d 100755 --- a/src/backend/people/settings.py +++ b/src/backend/people/settings.py @@ -218,6 +218,7 @@ class Base(Configuration): REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ( + "core.resource_server.authentication.ResourceServerAuthentication", "mozilla_django_oidc.contrib.drf.OIDCAuthentication", "rest_framework.authentication.SessionAuthentication", ),