How to get a refresh token with oauth in microsoft365?

2.7k Views Asked by At

I am trying to use microsoft365 and oauth to get an access and refresh token. According to Microsoft 365 docs, we need to use the "offline_access" scope to get a refresh token along with access token. However, The response I am getting does not contain a refresh token.

Here is the code I used:

    url = "https://login.microsoftonline.com/{}/oauth2/v2.0/token".format(tenant_id)

    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
    }

    data = {
        "client_id": client_id,
        "client_secret": client_secret,
        "grant_type": "client_credentials",
        "scope": "https://graph.microsoft.com/.default offline_access",
    }

    response = requests.post(url, headers=headers, data=data)

The response contains the access token like usual, but does not contain the refresh token despite using the offline_access scope. Could someone kindly tell me what the issue is?

2

There are 2 best solutions below

0
On BEST ANSWER

I agree with @junnas Client Credential Flow doesn’t return refresh token as user interaction is not present.

I tried to reproduce the same in my environment and got the results like below:

To get the refresh token, you need to choose user interactive flows such as Auth-Code Flow.

I created an Azure AD Application and added API permissions like below:

enter image description here

I generated auth-code using below endpoint:

https://login.microsoftonline.com/TenantID/oauth2/v2.0/authorize? 
client_id=ClientID
&response_type=code  
&redirect_uri=https://jwt.ms
&response_mode=query  
&scope=https://graph.microsoft.com/.default offline_access
&state=12345

enter image description here

I generated the access token and refresh token using below parameters:

GET https://login.microsoftonline.com/TenantID/oauth2/v2.0/token

client_id:ClientID
client_secret:ClientSecret
scope:https://graph.microsoft.com/.default offline_access
grant_type:authorization_code
redirect_uri:redirectURi
code:code

enter image description here

By using the above generated refresh token, I refreshed the access token successfully like below:

GET https://login.microsoftonline.com/TenantID/oauth2/v2.0/token

client_id:ClientID
grant_type:refresh_token
refresh_token:xxx
client_secret:xxx

enter image description here

0
On

You are using client credentials flow. It does not return a refresh token because you don't need one.

Refresh tokens are involved when a user logs in to your application. Since doing the authentication again would require that the user does the log in again, instead you get a refresh token to get new tokens.

But in the client credentials case re-authenticating is just a matter of sending the same request again. Refresh token would add nothing to this. Send the same request again before your token expires.