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.
21,647 questions
0 comments No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Dillon Silzer 57,401 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


  2. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  3. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  4. Raja Pothuraju 6,085 Reputation points Microsoft Vendor
    2024-07-18T19:26:04.14+00:00

    Hello @Qi,

    Thank you for your response.

    I see that your web app connects to an MSSQL database on Azure using a user-assigned managed identity, and you're seeking a method to automatically refresh the tokens when they expire. However, for user-assigned managed identities, it's not possible to generate refresh tokens.

    refresh_token - Not used by managed identities for Azure resources.

    Managed identity tokens are cached by the underlying Azure infrastructure for performance and resiliency purposes: the back-end services for managed identities maintain a cache per resource URI for around 24 hours. It can take several hours for changes to a managed identity's permissions to take effect, for example. Today, it is not possible to force a managed identity's token to be refreshed before its expiry. For more information, see Limitation of using managed identities for authorization.

    I hope this information is helpful. Please feel free to reach out if you have any further questions.

    Please "Accept the answer" if the information helped you. This will help us and others in the community as well.

    Thanks,
    Raja Pothuraju.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.