mke21
mke21

Reputation: 155

Mapping roles in AzureAD to Django groups

Okay, I can now do SSO in Django via AzureAD by using django-microsoft-auth. But I would like to manage the groups there as well. For that we configured to pass roles in the token. But how do I map those to Django groups? I don't seem to find any example for that.

Upvotes: 3

Views: 855

Answers (2)

xargs_rm
xargs_rm

Reputation: 1

I've used the MICROSOFT_AUTH_AUTHENTICATE_HOOK setting also. I didn't want to erase and re-add users to groups every time they logged in. This code will match the Azure Roles to Django Groups and update them accordingly on login.

from django.contrib.auth.models import Group
import jwt

def post_microsoft_auth(user, id_token, **kwargs):
    # This extracts the real id_token from the full token that was passed from Azure.
    correct_token = id_token.get('id_token')

    # Decode the token into usable json data
    token_data = jwt.decode(correct_token, options={"verify_signature": False})

    # Gets the list of Azure Roles the user is assigned to
    azure_roles = token_data.get('roles', [])

    # Get the list of Django Groups the current user belongs to. Sort the list.
    django_groups = sorted(list(user.groups.values_list('name', flat = True)))

    # If Azure Roles match Django Groups, do nothing. Else, call update_django_groups()
    if not azure_roles == django_groups:
        update_django_groups(user, azure_roles, django_groups)


def update_django_groups(user, azure_roles, django_groups):
    #Add user to Django Group for each Role assigned in Azure
    for role_name in azure_roles:
        if not user.groups.filter(name=role_name).exists():
            current_group, created = Group.objects.get_or_create(name=role_name)
            current_group.user_set.add(user)

    #Remove user from Django Group if the Role is no longer assigned in Azure
    for group in django_groups:
        if group not in azure_roles:
            current_django_group, created = Group.objects.get_or_create(name=group)
            current_django_group.user_set.remove(user)

Upvotes: 0

mke21
mke21

Reputation: 155

Found it. For anyone with the same question, you'll have to use the 'MICROSOFT_AUTH_AUTHENTICATE_HOOK' setting.

I made a module in my 'app' called aad.py:

import jwt
def add_to_group(user, token):
    from django.contrib.auth.models import Group
    id_token = token['id_token']
    token_data = jwt.decode(id_token, options={"verify_signature": False})
    roles = token_data.get('roles', [])
    user.groups.clear()
    for r in roles:
        current_group, created = Group.objects.get_or_create(name=r)
        current_group.user_set.add(user)

in the settings I added the following setting:

MICROSOFT_AUTH_AUTHENTICATE_HOOK = "myApp.aad.add_to_group"

Of course things could be neater, but it works for now.

Upvotes: 1

Related Questions