How to automatically refresh the azure access token using Django?

Qi 0 Reputation points
2024-07-04T16:44:36.11+00:00

I have a Django web app that connects to a mssql database on azure using a user assigned managed identity. The app use DefaultAzureCredential from azure.identity to get a azure token for the managed identity. However, after a while the token expires, the app cannot connect to the database anymore. How to automatically refresh the azure access token properly? My database config in setting.py is shown below. I tried several middleware approaches suggested by GPT4o, but all failed to refresh the token eventually.

def get_token():
    credential = DefaultAzureCredential(managed_identity_client_id = 'my-managed-identity-client-id')
    token = credential.get_token("https://database.windows.net/.default")
    return token.token
DATABASES = {
    'default': {
        'ENGINE': 'mssql',
        'NAME': 'my-db-name',
        'HOST': 'server-name',
        'PORT': '1433',
        "TOKEN": get_token(),
        'OPTIONS': {
            'driver': 'ODBC Driver 17 for SQL Server',
        },
    }
}

Microsoft Entra
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
20,368 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Dillon Silzer 55,476 Reputation points
    2024-07-04T17:44:20.7866667+00:00

    Hello,

    Perhaps this can assist:

    class MicrosoftView(APIView):
        permission_classes = ()
    
        def post(self, request):
            headers = {"Authorization": "Bearer " + request.data.get('token')}
            r = requests.get('https://graph.microsoft.com/v1.0/me/', headers=headers)
            data = json.loads(r.text)
            print(data)
    
            if 'error' in data:
                content = {'message': 'Wrong Microsoft token / This Microsoft token is already expired.'}
                return Response(content, status.HTTP_401_UNAUTHORIZED)
    
            try:
                user = models.CustomUser.objects.get(email=data['userPrincipalName'])
            except models.CustomUser.DoesNotExist:
                content = {'message': 'Your account doesn\'t exist'}
                return Response(content, status.HTTP_403_FORBIDDEN)
    
            token = RefreshToken.for_user(user)  # Generate token without username & password
            response = {
                'username': user.username,
                'access_token': str(token.access_token),
                'refresh_token': str(token)
            }
    
            return Response(response)
    
    

    Cited from https://www.reddit.com/r/django/comments/jixp7a/django_rest_framework_api_authentication_with/


    If this is helpful please accept as answer or upvote.

    Best regards,

    Dillon Silzer, Director | Cloudaen.com | Cloudaen Computing Solutions