Package: django-azure-active-directory-signin
Django Azure Active Directory Sign-In 🔑Sign-in users to your Django Web app with Azure Active Directory.Descriptiondjango-azure-active-directory-signinis a Django app which wrapsMSALpackage to sign in users with Microsoft's Azure Active Directory (OAuth 2.0 and OpenID Connect) in Django projects.The app includeslogin,logoutandcallbackauthentication views,
a customizable backend to validate, create user and extend user with extra attributes,
a decorator to protect individual views to protect individual views,
and middleware which allows the entire site to require user authentication by default,
with the ability to exempt specified views.The GitHub repository provides ademoDjango app to run local tests onhttpsprotocol thanks todjango-sslserver.This project is in no way affiliated with Microsoft Corporation.InstallationFrom PyPi:pipinstalldjango-azure-active-directory-signinConfigurationAzure App RegistrationRegister an application. You must have permission to manage applications in Azure Active Directory (Azure AD) on yourAzure account.Add a client secretinCertificates & secrets>Client secrets>New client secretand note it down.Copy yourclient_id,tenant_idandclient_secretand store them in environment variables (see.envfolder for sample) or better still in anAzure Key Vault.Add redirect URIlike so:https://<your-domain>/azure-signin/callbackhttps://127.0.0.1:8000/azure-signin/callbackhttps://localhost:8000/azure-signin/callbackSettingsAdd the following to yoursettings.py, replacing the variables in braces with the values
from your Azure app:INSTALLED_APPS+=["azure_signin",]AZURE_SIGNIN={"CLIENT_ID":os.environ.get("CLIENT_ID"),# Mandatory"CLIENT_SECRET":os.environ.get("CLIENT_SECRET"),# Mandatory"TENANT_ID":os.environ.get("TENANT_ID"),# Mandatory"SAVE_ID_TOKEN_CLAIMS":True,# Optional, default is False."RENAME_ATTRIBUTES":[("employeeNumber","employee_id"),("affiliationNumber","omk2"),],# Optional"REDIRECT_URI":"https://<domain>/azure-signin/callback",# Optional"SCOPES":["User.Read.All"],# Optional"AUTHORITY":"https://login.microsoftonline.com/"+os.environ.get("TENANT_ID"),# Optional Or https://login.microsoftonline.com/common if multi-tenant"LOGOUT_REDIRECT_URI":"https://<domain>/logout",# Optional"PUBLIC_URLS":["<public:view_name>",]# Optional, public views accessible by non-authenticated users}AUTHENTICATION_BACKENDS+=["azure_signin.backends.AzureSigninBackend",]LOGIN_URL="azure_signin:login"LOGIN_REDIRECT_URL="/"# Or any other endpointLOGOUT_REDIRECT_URL=LOGIN_REDIRECT_URLInstalled appsAdd the following to yourINSTALLED_APPS:INSTALLED_APPS+=["azure_signin",]Authentication backendConfigure the authentication backend:AUTHENTICATION_BACKENDS+=["azure_signin.backends.AzureSigninBackend",]URLsInclude the app's URLs in yoururlpatterns:fromdjango.urlsimportpath,includeurlpatterns+=[path("azure-signin/",include("azure_signin.urls",namespace="azure_signin")),]UsageAbstractUserAdd extra attributes to users withAZURE_SIGNIN["RENAME_ATTRIBUTES"]and Djangodjango.contrib.auth.models.AbstractUser.fromdjango.contrib.auth.modelsimportAbstractUserfromdjango.dbimportmodelsclassExtendedUser(AbstractUser):"""Extend user with extra attributes set in `AZURE_SIGNIN["RENAME_ATTRIBUTES"]`"""email=models.EmailField(unique=True,db_index=True)employee_id=models.IntegerField(null=True,default=None,unique=True,blank=True,db_index=True)omk2=models.CharField(max_length=5,null=True,default=None,db_index=True)hcm=models.CharField(max_length=7,null=True,default=None,db_index=True)BackendBackend can be subclassed to customize validation rules for user.importloggingfromazure_signin.backendsimportAzureSigninBackendlogger=logging.getLogger(__name__)classCustomAzureSigninBackend(AzureSigninBackend):"Subclass AzureSigninBackend to customize validation rules for user."defis_valid_user(self,user:dict,*args,**kwargs)->bool:"is_valid_user"output=super().is_valid_user(user,*args,**kwargs)try:"run extra checks here..."passexceptExceptionase:logger.exception(e)logger.debug("is_valid_user:%s",output)returnoutputDecoratorTo make user authentication a requirement for accessing an individual view, decorate the
view like so:fromazure_signin.decoratorsimportazure_signin_requiredfromdjango.shortcutsimportHttpResponse@azure_signin_requireddefprotected_view(request):returnHttpResponse("A view protected by the decorator")MiddlewareIf you want to protect your entire site by default, you can use the middleware by adding the
following to yoursettings.py:MIDDLEWARE+=["azure_signin.middleware.AzureSigninMiddleware",]Make sure you add the middleware after Django'ssessionandauthenticationmiddlewares so
that the request includes the session and user objects. Public URLs which need to be accessed by
non-authenticated users should be specified in thesettings.AZURE_SIGNIN["PUBLIC_URLS"], as
shown above.VS Code TasksThe GitHub repository provides commandsInstall,LaunchandTestsaccessible throughCommand Palette(pressCmd+Shift+P) then>Tasks: Run Tasks.All bash scripts are stored in.bashfolder.The virtual environment is propelled bypoetrywhich can be installed with Homebrewbrew install poetry.CreditsThis app is inspired by and builds on functionality inhttps://github.com/AgileTek/django-azure-auth, with both feature
improvements, code coverage and extended documentation.Readings 📚Quickstart: Add sign-in with Microsoft to a web app(docs.microsoft.com)Microsoft Graph REST API v1.0(docs.microsoft.com)Enable your Python Django web app to sign in users to your Azure Active Directorytenant with the Microsoft identity platform (github.com)SponsorshipIf this project helps you, you can offer me a cup of coffee ☕️ :-)