diff --git a/.env.example b/.env.example
index bc585be..212d195 100644
--- a/.env.example
+++ b/.env.example
@@ -4,6 +4,8 @@
SECRET_KEY=change-me-in-production
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
+# Server port (default: 8000)
+PORT=8000
# LLM Provider: "openai", "azure", or "azure_mistral"
LLM_PROVIDER=openai
@@ -51,6 +53,11 @@ SHAREPOINT_CLIENT_ID=
SHAREPOINT_CLIENT_SECRET=
SHAREPOINT_TENANT_ID=
+# Azure AD SSO (Microsoft login via allauth)
+AZURE_CLIENT_ID=
+AZURE_CLIENT_SECRET=
+AZURE_TENANT_ID=
+
# Confluence (optional)
CONFLUENCE_URL=
CONFLUENCE_USERNAME=
diff --git a/dashboard/templates/account/login.html b/dashboard/templates/account/login.html
index 1e56dd3..dc4e9aa 100644
--- a/dashboard/templates/account/login.html
+++ b/dashboard/templates/account/login.html
@@ -1,9 +1,23 @@
{% extends "account/base_auth.html" %}
-{% load i18n %}
+{% load i18n socialaccount %}
{% block title %}{% trans "Connexion" %} - SCORE{% endblock %}
{% block subtitle %}{% trans "Connectez-vous à votre compte" %}{% endblock %}
{% block content %}
+{% get_providers as socialaccount_providers %}
+
+{% if socialaccount_providers %}
+
+
+ {% trans "Se connecter avec Microsoft" %}
+
+
+
+ {% trans "ou" %}
+
+
+{% endif %}
+
{% if form.errors %}
{% trans "Identifiants invalides. Veuillez réessayer." %}
{% endif %}
diff --git a/score/middleware.py b/score/middleware.py
index 02a0ca3..036cb50 100644
--- a/score/middleware.py
+++ b/score/middleware.py
@@ -15,7 +15,8 @@ class ContentSecurityPolicyMiddleware:
"style-src 'self' 'unsafe-inline' cdn.jsdelivr.net",
"img-src 'self' data: blob:",
"font-src 'self' cdn.jsdelivr.net",
- "connect-src 'self'",
+ "connect-src 'self' login.microsoftonline.com",
+ "form-action 'self' login.microsoftonline.com",
"worker-src 'self' blob:",
"frame-src 'self'",
"object-src 'none'",
diff --git a/score/settings.py b/score/settings.py
index 7ca59d6..4f8e0c5 100644
--- a/score/settings.py
+++ b/score/settings.py
@@ -55,8 +55,8 @@
# Auth
"allauth",
"allauth.account",
- # "allauth.socialaccount",
- # "allauth.socialaccount.providers.microsoft",
+ "allauth.socialaccount",
+ "allauth.socialaccount.providers.microsoft",
# Celery
"django_celery_results",
"django_celery_beat",
@@ -151,6 +151,29 @@
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
+# --- Azure AD SSO (allauth social) ---
+AZURE_CLIENT_ID = env("AZURE_CLIENT_ID", default="")
+AZURE_CLIENT_SECRET = env("AZURE_CLIENT_SECRET", default="")
+AZURE_TENANT_ID = env("AZURE_TENANT_ID", default="")
+
+SOCIALACCOUNT_PROVIDERS = {
+ "microsoft": {
+ "APPS": [
+ {
+ "client_id": AZURE_CLIENT_ID,
+ "secret": AZURE_CLIENT_SECRET,
+ "settings": {
+ "tenant": AZURE_TENANT_ID or "common",
+ },
+ },
+ ],
+ },
+}
+
+SOCIALACCOUNT_AUTO_SIGNUP = True
+SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = True
+SOCIALACCOUNT_LOGIN_ON_GET = True
+
# --- Session security ---
SESSION_COOKIE_AGE = 3600 * 8 # 8 hours
SESSION_SAVE_EVERY_REQUEST = True # Reset expiry on each request