Prepare authentication via OIDC

This commit is contained in:
Luca 2023-08-10 21:41:11 +02:00
parent 81fecd24af
commit 6987ad9d7e
6 changed files with 75 additions and 4 deletions

49
ljg/core/auth.py Normal file
View File

@ -0,0 +1,49 @@
from django.conf import settings
from django.contrib.auth.models import Permission
from django.db import transaction
from mozilla_django_oidc.auth import \
OIDCAuthenticationBackend as BaseOIDCAuthenticationBackend
from .models import OIDCUser
def get_permissions(claims):
return Permission.objects.filter(
codename__in=claims.get("resource_access")[settings.OIDC_RP_CLIENT_ID]["roles"]
)
class OIDCAuthenticationBackend(BaseOIDCAuthenticationBackend):
@transaction.atomic
def create_user(self, claims):
user = self.UserModel.objects.create_user(
claims.get("preferred_username"), claims.get("email")
)
user.first_name = claims.get("given_name")
user.last_name = claims.get("family_name")
user.user_permissions.set(get_permissions(claims))
user.save()
OIDCUser.objects.create(uuid=claims.get("sub"), user=user)
return user
def update_user(self, user, claims):
user.user_permissions.set(get_permissions(claims))
user.save()
return user
def filter_users_by_claims(self, claims):
uuid = claims.get("sub")
if not uuid:
return self.UserModel.objects.none()
try:
oidc_user = OIDCUser.object.get(uuid=uuid)
return [oidc_user.user]
except OIDCUser.DoesNotExist:
return self.UserModel.objects.none()
def verify_claims(self, claims):
return settings.OIDC_RP_CLIENT_ID in claims.get("resource_access")

View File

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View File

@ -0,0 +1,3 @@
from .auth import OIDCUser
__all__ = ("OIDCUser",)

7
ljg/core/models/auth.py Normal file
View File

@ -0,0 +1,7 @@
from django.contrib.auth.models import User
from django.db import models
class OIDCUser(models.Model):
uuid = models.UUIDField(primary_key=True)
user = models.OneToOneField(User, on_delete=models.CASCADE)

View File

@ -42,6 +42,7 @@ INSTALLED_APPS = [
"django.contrib.messages",
"django.contrib.staticfiles",
"ljg.core.apps.CoreConfig",
"mozilla_django_oidc",
]
MIDDLEWARE = [
@ -52,6 +53,7 @@ MIDDLEWARE = [
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"mozilla_django_oidc.middleware.SessionRefresh",
]
ROOT_URLCONF = "ljg.urls"
@ -134,3 +136,15 @@ STATIC_URL = "static/"
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
APP_TITLE = getenv("APP_TITLE", "ljg.sh")
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend",
"ljg.core.auth.OIDCAuthenticationBackend",
)
OIDC_OP_AUTHORIZATION_ENDPOINT = getenv("OIDC_OP_AUTHORIZATION_ENDPOINT", "")
OIDC_OP_TOKEN_ENDPOINT = getenv("OIDC_OP_TOKEN_ENDPOINT", "")
OIDC_OP_USER_ENDPOINT = getenv("OIDC_OP_USER_ENDPOINT", "")
OIDC_RP_CLIENT_ID = getenv("OIDC_RP_CLIENT_ID", "")
OIDC_RP_CLIENT_SECRET = getenv("OIDC_RP_CLIENT_SECRET", "")

View File

@ -15,8 +15,9 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.urls import include, path
urlpatterns = [
path("admin/", admin.site.urls),
path("oidc/", include("mozilla_django_oidc.urls")),
]