From e929fcc682f4cc2c1628aed645350b4e35d7d200 Mon Sep 17 00:00:00 2001 From: Quentin BEY Date: Fri, 2 May 2025 17:11:51 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=A9(resource-server)=20open=20all=20AP?= =?UTF-8?q?Is=20to=20RS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This provides a base configuration to allow to access all API via OIDC resource server authentication. --- src/backend/core/api/viewsets.py | 10 +++--- src/backend/core/urls.py | 2 ++ src/backend/impress/settings.py | 55 ++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index 5e89e11c..e0e7c82f 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -26,6 +26,7 @@ import requests import rest_framework as drf from botocore.exceptions import ClientError from lasuite.malware_detection import malware_detection +from lasuite.oidc_resource_server.authentication import ResourceServerAuthentication from rest_framework import filters, status, viewsets from rest_framework import response as drf_response from rest_framework.permissions import AllowAny @@ -430,9 +431,7 @@ class DocumentViewSet( ordering = ["-updated_at"] ordering_fields = ["created_at", "updated_at", "title"] pagination_class = Pagination - permission_classes = [ - permissions.DocumentAccessPermission, - ] + permission_classes = [permissions.DocumentAccessPermission] queryset = models.Document.objects.all() serializer_class = serializers.DocumentSerializer ai_translate_serializer_class = serializers.AITranslateSerializer @@ -669,7 +668,10 @@ class DocumentViewSet( return self.get_response_for_queryset(queryset) @drf.decorators.action( - authentication_classes=[authentication.ServerToServerAuthentication], + authentication_classes=[ + authentication.ServerToServerAuthentication, + ResourceServerAuthentication, + ], detail=False, methods=["post"], permission_classes=[permissions.IsAuthenticated], diff --git a/src/backend/core/urls.py b/src/backend/core/urls.py index 05441895..fae84820 100644 --- a/src/backend/core/urls.py +++ b/src/backend/core/urls.py @@ -4,6 +4,7 @@ from django.conf import settings from django.urls import include, path, re_path from lasuite.oidc_login.urls import urlpatterns as oidc_urls +from lasuite.oidc_resource_server.urls import urlpatterns as resource_server_urls from rest_framework.routers import DefaultRouter from core.api import viewsets @@ -44,6 +45,7 @@ urlpatterns = [ [ *router.urls, *oidc_urls, + *resource_server_urls, re_path( r"^documents/(?P[0-9a-z-]*)/", include(document_related_router.urls), diff --git a/src/backend/impress/settings.py b/src/backend/impress/settings.py index d1b4a15d..ea4335b0 100755 --- a/src/backend/impress/settings.py +++ b/src/backend/impress/settings.py @@ -328,6 +328,7 @@ class Base(Configuration): REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ( "rest_framework.authentication.SessionAuthentication", + "lasuite.oidc_resource_server.authentication.ResourceServerAuthentication", ), "DEFAULT_PARSER_CLASSES": [ "rest_framework.parsers.JSONParser", @@ -592,6 +593,60 @@ class Base(Configuration): default=True, environ_name="ALLOW_LOGOUT_GET_METHOD", environ_prefix=None ) + # OIDC - Docs as a resource server + OIDC_OP_URL = values.Value( + default=None, environ_name="OIDC_OP_URL", environ_prefix=None + ) + OIDC_OP_INTROSPECTION_ENDPOINT = values.Value( + environ_name="OIDC_OP_INTROSPECTION_ENDPOINT", environ_prefix=None + ) + OIDC_VERIFY_SSL = values.BooleanValue( + default=True, environ_name="OIDC_VERIFY_SSL", environ_prefix=None + ) + OIDC_TIMEOUT = values.IntegerValue( + default=3, environ_name="OIDC_TIMEOUT", environ_prefix=None + ) + OIDC_PROXY = values.Value(None, environ_name="OIDC_PROXY", environ_prefix=None) + + OIDC_RS_BACKEND_CLASS = "lasuite.oidc_resource_server.backend.ResourceServerBackend" + OIDC_RS_AUDIENCE_CLAIM = values.Value( # The claim used to identify the audience + default="client_id", environ_name="OIDC_RS_AUDIENCE_CLAIM", environ_prefix=None + ) + OIDC_RS_PRIVATE_KEY_STR = values.Value( + default=None, + environ_name="OIDC_RS_PRIVATE_KEY_STR", + environ_prefix=None, + ) + OIDC_RS_ENCRYPTION_KEY_TYPE = values.Value( + default="RSA", + environ_name="OIDC_RS_ENCRYPTION_KEY_TYPE", + environ_prefix=None, + ) + OIDC_RS_ENCRYPTION_ALGO = values.Value( + default="RSA-OAEP", + environ_name="OIDC_RS_ENCRYPTION_ALGO", + environ_prefix=None, + ) + OIDC_RS_ENCRYPTION_ENCODING = values.Value( + default="A256GCM", + environ_name="OIDC_RS_ENCRYPTION_ENCODING", + environ_prefix=None, + ) + OIDC_RS_CLIENT_ID = values.Value( + None, environ_name="OIDC_RS_CLIENT_ID", environ_prefix=None + ) + OIDC_RS_CLIENT_SECRET = values.Value( + None, + environ_name="OIDC_RS_CLIENT_SECRET", + environ_prefix=None, + ) + OIDC_RS_SIGNING_ALGO = values.Value( + default="ES256", environ_name="OIDC_RS_SIGNING_ALGO", environ_prefix=None + ) + OIDC_RS_SCOPES = values.ListValue( + [], environ_name="OIDC_RS_SCOPES", environ_prefix=None + ) + # AI service AI_FEATURE_ENABLED = values.BooleanValue( default=False, environ_name="AI_FEATURE_ENABLED", environ_prefix=None