diff --git a/config/settings/base.py b/config/settings/base.py index e15f643a..91399b19 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -26,6 +26,8 @@ INSTALLED_APPS = [ "django.contrib.gis", "django.contrib.auth", + # OIDC / ProConnect : doit être chargé après `django.contrib.auth` + "mozilla_django_oidc", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", @@ -64,8 +66,19 @@ "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "csp.middleware.CSPMiddleware", + # Rafraichissement du token ProConnect + "mozilla_django_oidc.middleware.SessionRefresh", ] +# OIDC / ProConnect +AUTHENTICATION_BACKENDS = [ + "dora.oidc.OIDCAuthenticationBackend", +] + +# Permet de garder le comportement d'identification "standard" (e-mail/password) +ACCOUNT_EMAIL_REQUIRED = True +ACCOUNT_AUTHENTICATION_METHOD = "email" + ROOT_URLCONF = "config.urls" TEMPLATES = [ @@ -287,7 +300,7 @@ # Modération : MATTERMOST_HOOK_KEY = os.getenv("MATTERMOST_HOOK_KEY") -# INCLUSION-CONNECT / PRO-CONNECT +# INCLUSION-CONNECT IC_ISSUER_ID = os.getenv("IC_ISSUER_ID") IC_AUTH_URL = os.getenv("IC_AUTH_URL") IC_TOKEN_URL = os.getenv("IC_TOKEN_URL") @@ -296,7 +309,59 @@ IC_CLIENT_ID = os.getenv("IC_CLIENT_ID") IC_CLIENT_SECRET = os.getenv("IC_CLIENT_SECRET") -# Recherches sauvagardées : +# OIDC / PROCONNECT +PC_CLIENT_ID = os.getenv("PC_CLIENT_ID") +PC_CLIENT_SECRET = os.getenv("PC_CLIENT_SECRET") +PC_DOMAIN = os.getenv("PC_DOMAIN", "fca.integ01.dev-agentconnect.fr") +PC_ISSUER = os.getenv("PC_ISSUER", f"{PC_DOMAIN}/api/v2") +PC_AUTHORIZE_PATH = os.getenv("PC_AUTHORIZE_PATH", "authorize") +PC_TOKEN_PATH = os.getenv("PC_TOKEN_PATH", "token") +PC_USERINFO_PATH = os.getenv("PC_USERINFO_PATH", "userinfo") + +# ProConnect à besoin de ce setting pour le logout +FRONTEND_URL = os.getenv("FRONTEND_URL") + +# mozilla_django_oidc: +OIDC_RP_CLIENT_ID = os.getenv("PC_CLIENT_ID") +OIDC_RP_CLIENT_SECRET = os.getenv("PC_CLIENT_SECRET") +OIDC_RP_SCOPES = "openid given_name usual_name email siret custom uid" + +# `mozilla_django_oidc` n'utilise pas de discovery / .well-known +# on définit donc chaque endpoint +OIDC_RP_SIGN_ALGO = "RS256" +OIDC_OP_JWKS_ENDPOINT = f"https://{PC_ISSUER}/jwks" +OIDC_OP_AUTHORIZATION_ENDPOINT = f"https://{PC_ISSUER}/authorize" +OIDC_OP_TOKEN_ENDPOINT = f"https://{PC_ISSUER}/token" +OIDC_OP_USER_ENDPOINT = f"https://{PC_ISSUER}/userinfo" +OIDC_OP_LOGOUT_ENDPOINT = f"https://{PC_ISSUER}/session/end" + +# Les paramètres suivants servent à adapter la configuration OIDC +# de `mozilla-django_oidc` pour pouvoir fonctionner dans le contexte +# spécifique à DORA et ProConnect. + +# OIDC : intervalle de rafraichissement du token (4h) +OIDC_RENEW_ID_TOKEN_EXPIRY_SECONDS = 4 * 60 * 60 + +# OIDC : nécessaire pour la gestion de la fin de session coté ProConnect +OIDC_STORE_ID_TOKEN = True +ALLOW_LOGOUT_GET_METHOD = True + +# obligatoire pour ProConnect: à passer en paramètre de requête supplémentaire +# lors de la première phase du flow OIDC +OIDC_AUTH_REQUEST_EXTRA_PARAMS = {"acr_values": "eidas1"} + +# OIDC : redirection vers le front DORA en cas de succès de l'identification +# necessaire pour la gestion de "l'URL suivant" (`next_url`) +LOGIN_REDIRECT_URL = "/oidc/logged_in/" + +# OIDC : redirection vers l'acceuil du front DORA pour la déconnexion +LOGOUT_REDIRECT_URL = FRONTEND_URL + +# OIDC : permet de préciser quelle est la class/vue en charge du callback dans le flow OIDC +# (essentiellement pour la gestion du `next_url`). +OIDC_CALLBACK_CLASS = "dora.oidc.views.CustomAuthorizationCallbackView" + +# Recherches sauvegardées : INCLUDES_DI_SERVICES_IN_SAVED_SEARCH_NOTIFICATIONS = ( os.getenv("INCLUDES_DI_SERVICES_IN_SAVED_SEARCH_NOTIFICATIONS") == "true" ) @@ -353,7 +418,6 @@ EMAIL_PORT = os.getenv("EMAIL_PORT") EMAIL_USE_TLS = True EMAIL_DOMAIN = os.getenv("EMAIL_DOMAIN") -FRONTEND_URL = os.getenv("FRONTEND_URL") SUPPORT_EMAIL = os.getenv("SUPPORT_EMAIL") SUPPORT_LINK = "https://aide.dora.inclusion.beta.gouv.fr" diff --git a/config/settings/test.py b/config/settings/test.py index 32efb52d..e5e35388 100644 --- a/config/settings/test.py +++ b/config/settings/test.py @@ -40,5 +40,7 @@ IC_TOKEN_URL = os.getenv("IC_TOKEN_URL", "https://whatever-oidc-token-url.com") AWS_STORAGE_BUCKET_NAME = os.getenv("AWS_STORAGE_BUCKET_NAME", "dora") SIB_ONBOARDING_LIST = os.getenv("SIB_ONBOARDING_LIST", "1") -SIB_ONBOARDING_PUTATIVE_MEMBER_LIST = os.getenv("SIB_ONBOARDING_PUTATIVE_MEMBER_LIST", "2") +SIB_ONBOARDING_PUTATIVE_MEMBER_LIST = os.getenv( + "SIB_ONBOARDING_PUTATIVE_MEMBER_LIST", "2" +) SIB_ONBOARDING_MEMBER_LIST = os.getenv("SIB_ONBOARDING_MEMBER_LIST", "3") diff --git a/config/urls.py b/config/urls.py index f76b534f..b9e30085 100644 --- a/config/urls.py +++ b/config/urls.py @@ -112,7 +112,10 @@ urlpatterns = [ *private_api_patterns, *di_api_patterns, + # anciennes routes Inclusion-Connect (en attente de suppression) *oidc_patterns, + # nouvelles routes OIDC pour ProConnect + path("oidc/", include("mozilla_django_oidc.urls")), ] if settings.PROFILE: diff --git a/requirements/base.txt b/requirements/base.txt index cf4aa35f..89ba4d85 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -8,6 +8,7 @@ django-storages[boto3]==1.14.4 djangorestframework-camel-case==1.4.2 djangorestframework-gis==1.1 djangorestframework==3.15.2 +mozilla-django-oidc==4.0.1 furl==2.1.3 hiredis==3.0.0 humanize==4.10.0