mozilla / mozilla-django-oidc

A django OpenID Connect library

Home Page:https://mozilla-django-oidc.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

User Object accessible in request.user but not Persistent in the database

cyril36 opened this issue · comments

Hello,

Use case

I dont want to manage my users created in Django and keep them only on the identity provider (in my case Keycloak)
Currently Mozilla-django-oidc stores the user information from identity provider into the django database.
I have added some code to do not save the user information into the database but still be able to get a User object and request.user object out of the identity provider

  1. Is it a good approach?
  2. It will only work if a token header is present (authenticationSession wont work as it relies on users information stored in the database)

Way of working

Settings :
An extra variable is needed :
OIDC_PERSISTENT_USER
Default Value : True
I have added this variable in the settings :

OIDC_PERSISTENT_USER = False

Code block :
Add the Function def init_user(self,claims): in OIDCAuthenticationBackend:
(i have defined this function with username as it is by default but i might not make sense as in this case the username may always change - in my use case i dont use username )

def init_user(self,claims):
      user = self.UserModel()
      user.email = claims.get('email')
      user.username = self.get_username(claims)
      return user

redefine def get_or_create_user(self, access_token, id_token, payload): in OIDCAuthenticationBackend

        user_info = self.get_userinfo(access_token, id_token, payload)

        claims_verified = self.verify_claims(user_info)
        if not claims_verified:
            msg = 'Claims verification failed'
            raise SuspiciousOperation(msg)

        if not self.get_settings('OIDC_PERSISTENT_USER', True):
          return self.init_user(user_info)

        # email based filtering
        users = self.filter_users_by_claims(user_info)

        if len(users) == 1:
            return self.update_user(users[0], user_info)
        elif len(users) > 1:

update def create_user(self, claims): in OIDCAuthenticationBackend

def create_user(self, claims):
        self.init_user(claims)
        user.save()
        return user

With this change the user wont be created in database but still be added to request.user object if the authentication works just by adding OIDC_PERSISTENT_USER = False to settings.py

Please let me know if it is a good approach and if it might be needed.

Cyril