Internals

User model

class django_compref_keycloak.models.ComprefKeycloakUser(*args, **kwargs)

We extend the existing user model without replacing it. So app can still do what they want but we also have our place to store attributes.

Docs: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model

exception DoesNotExist
exception MultipleObjectsReturned

Backend

class django_compref_keycloak.backend.CompRefKeycloakAuthenticationBackend(*args, **kwargs)

Custom authentication backend for our Keycloak, that has different federated identity provides connected.

The federated identity providers give us different types of data, sometimes we do not have mail addresses or names. Depending on the app config, different claims are checked to determine if the user is allowed to log in.

create_user(claims)

Called on first login when no user object exists

update_user(user, claims)

Called on login when the user already exists, just update all attributes

verify_claims(claims)

This is the first time, we see the claims. So we do some sanity checks here, as the overall situation is pretty complex.

If DEBUG is enabled, we print the claims and some more information (logging framework is not used on purpose so that we do not need to touch the logging config of the app)

django_compref_keycloak.backend.generate_username(email)

The username is based on the email claim.

However, we somethimes set the email claim to something that is not the email address (shibboleth). But this is not important here. For Django: username = email.

django_compref_keycloak.backend.logout_url(request)

URL for logout at OpenID Connect provider.