One great way to connect to the database for development and production in Django is to use the Microsoft Entra / Azure Active Directory option to authenticate users. This is supported through the MSSQL database backend for Django. This means, you can add users or groups from Microsoft Entra to the database users and assign them permissions. They can then login using their Entra identity.
Create the user or group in the database
First, you will have to create the user or group in the database via:
CREATE USER [your-entra-group] FROM EXTERNAL PROVIDER;
ALTER USER [your-entra-group] WITH DEFAULT_SCHEMA=[dbo]
This makes your database recognize the user or group and ensures they can log in. You can then assign them any permissions you see fit.
Make sure you are logged in
Now, make sure you are either logged in through Azure CLI or in Visual Studio Code (if you are using this editor) with your Microsoft account that you will also use for the authentication and that has access to the database.
Change your Django config
Then, you have to update your Django config so that it uses the token method to authenticate with the database.
First, you have to install the azure-identity
package (add it to your requirements.txt
/ pyproject.toml
/ your package management). Update your settings.py
with some helper:
import time from azure.core.credentials import AccessToken
from azure.core.exceptions import ClientAuthenticationError
from azure.identity import DefaultAzureCredential class DatabaseToken(str): cached_token: AccessToken | None = None def __new__(cls) -> None: instance = super().__new__(cls, "") instance.get_access_token() return instance def token_is_valid(self) -> bool: if self.cached_token is None: return False return self.cached_token.expires_on > time.time() def get_new_token(self) -> AccessToken: try: return DefaultAzureCredential().get_token("https://database.windows.net/.default") except ClientAuthenticationError: pass return DefaultAzureCredential(exclude_shared_token_cache_credential=True).get_token( "https://database.windows.net/.default" ) def get_access_token(self) -> AccessToken: if self.token_is_valid(): return self.cached_token self.cached_token = self.get_new_token() return self.cached_token def encode(self, *args, **kwargs) -> bytes: return self.get_access_token().token.encode(*args, **kwargs)
Then, you have to update your database configuration part of settings.py
:
DATABASES = { "default": { "ENGINE": "mssql", "NAME": "YOUR_DATABASE", "TOKEN": DatabaseToken(), "HOST": "YOUR_URL", "CONN_MAX_AGE": 30 * 60, # max of 30 min, since AT is valid for 60 min
"OPTIONS": {"driver": "ODBC Driver 18 for SQL Server"}, "TEST": {"NAME": "YOUR_TEST_DATABASE"}, "TIME_ZONE": "UTC", }
}
You will want to update the name of your database and also your host. We are using ODBC Driver 18 here which you might want to update depending on the specific driver you are using.
This might seem more difficult then it has to be. We could also just use one line: DefaultAzureCredential().get_token("https://database.windows.net/.default")
.
I have found that this sometimes leads to problems depending on the specifics of the development setup. Sometimes it will use a token from Azure CLI and sometimes from the shared token cache for which not a lot of documentation exists. Either operation might fail which will be a pain to debug. The code above makes sure the token retrieval “just works”.
Summary
Setting up token authentication for MSSQL databases with Django is quite easy thanks to the support for the specification of the token as part of the login credentials. You will have to give your Entra user or a group that your user is part of access to the database, login using that user, and then adjust your settings.py
.