Fix OIDC authentication

This commit is contained in:
Luca 2023-10-11 17:48:04 +02:00
parent 8522e32ee6
commit f87dd17bdc
4 changed files with 50 additions and 4 deletions

View File

@ -4,8 +4,14 @@ DATABASE_URL=
DEBUG=no
SECRET_KEY=
# for Keycloak, see https://{your keycloak host}/realms/{your realm}/.well-known/openid-configuration
OIDC_OP_AUTHORIZATION_ENDPOINT=
OIDC_OP_JWKS_ENDPOINT=
OIDC_OP_TOKEN_ENDPOINT=
OIDC_OP_USER_ENDPOINT=
OIDC_RP_CLIENT_ID=
OIDC_RP_CLIENT_SECRET=
# defaults to RS256
OIDC_RP_SIGN_ALGO=

View File

@ -9,6 +9,10 @@ from .models import OIDCUser
def get_permissions(claims):
roles = claims.get("resource_access")
if roles is None or settings.OIDC_RP_CLIENT_ID not in roles:
return Permission.objects.none()
return Permission.objects.filter(
codename__in=claims.get("resource_access")[settings.OIDC_RP_CLIENT_ID]["roles"]
)
@ -20,8 +24,8 @@ class OIDCAuthenticationBackend(BaseOIDCAuthenticationBackend):
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.first_name = claims.get("given_name", "")
user.last_name = claims.get("family_name", "")
user.user_permissions.set(get_permissions(claims))
user.save()
@ -30,6 +34,7 @@ class OIDCAuthenticationBackend(BaseOIDCAuthenticationBackend):
return user
def update_user(self, user, claims):
user.email = claims.get("email") or user.email
user.user_permissions.set(get_permissions(claims))
user.save()
@ -41,10 +46,11 @@ class OIDCAuthenticationBackend(BaseOIDCAuthenticationBackend):
return self.UserModel.objects.none()
try:
oidc_user = OIDCUser.object.get(uuid=uuid)
oidc_user = OIDCUser.objects.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")
roles = claims.get("resource_access")
return roles is not None and settings.OIDC_RP_CLIENT_ID in roles

View File

@ -0,0 +1,29 @@
# Generated by Django 4.2.4 on 2023-10-11 14:47
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="OIDCUser",
fields=[
("uuid", models.UUIDField(primary_key=True, serialize=False)),
(
"user",
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View File

@ -137,9 +137,14 @@ AUTHENTICATION_BACKENDS = (
"ljg.core.auth.OIDCAuthenticationBackend",
)
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/"
OIDC_OP_AUTHORIZATION_ENDPOINT = env.str("OIDC_OP_AUTHORIZATION_ENDPOINT", "")
OIDC_OP_JWKS_ENDPOINT = env.str("OIDC_OP_JWKS_ENDPOINT", "")
OIDC_OP_TOKEN_ENDPOINT = env.str("OIDC_OP_TOKEN_ENDPOINT", "")
OIDC_OP_USER_ENDPOINT = env.str("OIDC_OP_USER_ENDPOINT", "")
OIDC_RP_CLIENT_ID = env.str("OIDC_RP_CLIENT_ID", "")
OIDC_RP_CLIENT_SECRET = env.str("OIDC_RP_CLIENT_SECRET", "")
OIDC_RP_SIGN_ALGO = env.str("OIDC_RP_SIGN_ALGO", "RS256")