Skip to content

Use custom roles for authorisation in Django web applications

In this guide you will learn how to add custom roles to your application which are powered by Entra groups. Entra groups can be tied to Lookup groups providing a powerful and delegated means to add custom authorisation to your applications.

Our example

We will use the case study of wanting to restrict an application to only staff members. We'll also use the example of a Django application which is using python-social-auth for authentication.

Important

Guides for other web frameworks are welcome.

UIS provide some centrally managed groups which will be useful here. In particular the group 1f440b90-597d-45b4-9a0d-11707f784de7 contains all the staff members of the University.

We will be re-using the "Punt Booker" example from the guide on how to add SSO to your web application.

Prerequisites

Follow the steps in how to add SSO to your web application to register an Entra ID sign in application.

Follow the steps in hot to configure Django to use SSO.

Add the custom role

Add a custom role to the application configurations in the Entra ID Application Factory. For example, for the production application, the configuration will look like the following. Additional lines have been highlighted.

applications/production/punt-booker-production.yaml
type: sign-in

display_name: Punt Booker
logo_image: punt-booker.png

web_redirect_uris:
  - https://punt-booker.apps.cam.ac.uk/accounts/complete/azuread-tenant-oauth2/

credential_secrets:
  sign_in:
    template: default
    iam_policy:
      "roles/secretmanager.secretAccessor":
        - webapp@punt-booker-prod.iam.gserviceaccount.com

roles:
  staff:
    description: "Staff"
    display_name: "Staff"
    principal_object_ids:
      - "1f440b90-597d-45b4-9a0d-11707f784de7"

Tip

You can add more than one group id to a custom role. A user will be granted that role if they are a member of any of the groups.

Restrict views

The roles claim will now be available in the extra_data associated with the social user object. For example, you can create a decorator which requires that the logged in user be a staff member:

from social_django.models import UserSocialAuth
from django.contrib.auth.decorators import user_passes_test


def is_staff(user):
    # A non-signed in user is not staff.
    if user is None or user.is_anonymous():
        return False

    # A user without an Entra ID social auth record is not staff.
    try:
        social_auth = user.social_auth.get(provider="azuread-tenant-oauth2")
    except UserSocialAuth.DoesNotExist:
        return False

    # Only users with the "staff" role are staff.
    return "staff" in social_auth.extra_data.get("roles", [])


@user_passes_test(is_staff)
def my_view(request):
    # ...

Summary

In this guide we saw how to use custom roles in applications to provide authorisation in Django applications.

Next steps