0
votes

I'm trying to implement the Azure AD OAuth authentication for our Django app and I would be doing that with Azure AD as an OAuth provider. So now I wanted to know how securely we can store the OAuth access/refresh tokens in the DB that we receive from Azure AD or any OAuth provider.

I want to store the user's access token in DB because we have a feature in our web app where users can send an email with their email ID and we have a periodic job that runs every half an hour and it's gonna fetch user's mails based on a specific subject line. This we're gonna do with the help of Microsoft's Graph API and in order to call Microsoft Graph API, the web app should store the user's access token may be in the DB. But my concern is once we receive the access and refresh token, it shouldn't be accessed by anyone once we store it in the DB. So how securely or in an encrypted way we can store the OAuth2 access tokens in Django.

I have gone through a few articles, QnA, and forums on this concern but wanted to hear from the Django community as well.

Thanks in advance.

1
Could you pls add more description on your 'sending email' scenario? In my opinion, access token and refresh token are both have expired time, and we usually stored refresh token in key vault and when need to use access token to call an api, we'll store the new refresh token and next time we will use refresh token to generate a new access token first to avoid token expired.tiny-wa

1 Answers

0
votes

Let's start from sending email by graph(https://graph.microsoft.com/v1.0/users/{userId}/sendMail). I've done some test, here's the detail.

  1. When I used credential flow to generate an access token, I can't use it to send email with an error like 'ErrorAccessDenied', it means that we can't generate a token that can be used for many accounts.

  2. When I used auth code flow to generate an access token, I can't use it to send email when I set a different user id with the id that used to generate token in the api url. In this scenario, I also get the same error as above.

  3. When I used ropc flow and I can send email successfully with it, this means I will send email successfully only when I used the correct user id and token.

Error message when failed to send email:

{
    "error":{
    "code": "ErrorAccessDenied",
         "message": "Access is denied. Check credentials and try again."
    }
}

And according to the test result, I think if you decide to store the tokens into the database, you can save it inline with the user id, so when your periodic job executed, your program can query for the correct token which could be decoded first to check if it is expired, and use it to send email.

If I misunderstand in some place, pls point my error out, thanks.