Update web/core/auth_oidc.py
This commit is contained in:
parent
47bcc0c33c
commit
c0acced574
@ -1,43 +1,58 @@
|
|||||||
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
|
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
|
||||||
|
|
||||||
|
|
||||||
class AuthentikOIDCBackend(OIDCAuthenticationBackend):
|
class AuthentikOIDCBackend(OIDCAuthenticationBackend):
|
||||||
"""
|
"""
|
||||||
Minimal, safe backend:
|
Custom backend to integrate Authentik OIDC with existing Django users
|
||||||
- preserves existing local auth (ModelBackend stays enabled)
|
without breaking local authentication.
|
||||||
- creates/updates Django users from Authentik claims
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def filter_users_by_claims(self, claims):
|
def filter_users_by_claims(self, claims):
|
||||||
# Prefer stable identifiers. Authentik often provides email + preferred_username.
|
|
||||||
email = (claims.get("email") or "").strip().lower()
|
email = (claims.get("email") or "").strip().lower()
|
||||||
username = (claims.get("preferred_username") or claims.get("username") or "").strip()
|
username = (
|
||||||
|
claims.get("preferred_username")
|
||||||
|
or claims.get("username")
|
||||||
|
or ""
|
||||||
|
).strip()
|
||||||
|
|
||||||
# If you want "email is identity", use email matching first:
|
# 1) Prefer matching by email
|
||||||
if email:
|
if email:
|
||||||
return self.UserModel.objects.filter(email__iexact=email)
|
qs = self.UserModel.objects.filter(email__iexact=email)
|
||||||
|
if qs.exists():
|
||||||
|
return qs
|
||||||
|
|
||||||
# Fallback to username matching if no email
|
# 2) Fallback to username match (critical for existing local users)
|
||||||
if username:
|
if username:
|
||||||
return self.UserModel.objects.filter(username__iexact=username)
|
qs = self.UserModel.objects.filter(username__iexact=username)
|
||||||
|
if qs.exists():
|
||||||
|
return qs
|
||||||
|
|
||||||
|
# 3) Otherwise, no match -> create user
|
||||||
return self.UserModel.objects.none()
|
return self.UserModel.objects.none()
|
||||||
|
|
||||||
def create_user(self, claims):
|
def create_user(self, claims):
|
||||||
user = super().create_user(claims)
|
user = super().create_user(claims)
|
||||||
|
|
||||||
email = (claims.get("email") or "").strip().lower()
|
email = (claims.get("email") or "").strip().lower()
|
||||||
username = (claims.get("preferred_username") or claims.get("username") or email or "").strip()
|
username = (
|
||||||
|
claims.get("preferred_username")
|
||||||
|
or claims.get("username")
|
||||||
|
or email
|
||||||
|
or ""
|
||||||
|
).strip()
|
||||||
|
|
||||||
if username:
|
|
||||||
user.username = username
|
|
||||||
if email:
|
if email:
|
||||||
user.email = email
|
user.email = email
|
||||||
|
|
||||||
# Optional nice-to-have mappings
|
# Only set username if Django hasn't already set one
|
||||||
|
if username and not user.username:
|
||||||
|
user.username = username
|
||||||
|
|
||||||
user.first_name = claims.get("given_name", "") or user.first_name
|
user.first_name = claims.get("given_name", "") or user.first_name
|
||||||
user.last_name = claims.get("family_name", "") or user.last_name
|
user.last_name = claims.get("family_name", "") or user.last_name
|
||||||
|
|
||||||
user.set_unusable_password() # SSO-only unless you explicitly set local passwords
|
# SSO-only account unless you explicitly add a password later
|
||||||
|
user.set_unusable_password()
|
||||||
user.save()
|
user.save()
|
||||||
return user
|
return user
|
||||||
|
|
||||||
@ -46,7 +61,6 @@ class AuthentikOIDCBackend(OIDCAuthenticationBackend):
|
|||||||
if email and user.email.lower() != email:
|
if email and user.email.lower() != email:
|
||||||
user.email = email
|
user.email = email
|
||||||
|
|
||||||
# keep username stable once set, unless you *want* it to track upstream changes
|
|
||||||
user.first_name = claims.get("given_name", "") or user.first_name
|
user.first_name = claims.get("given_name", "") or user.first_name
|
||||||
user.last_name = claims.get("family_name", "") or user.last_name
|
user.last_name = claims.get("family_name", "") or user.last_name
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user