Microsoft identity platform and OAuth 2.0 authorization code flow

The OAuth 2.0 authorization code grant type, or auth code flow, enables a client application to obtain authorized access to protected resources like web APIs. The auth code flow requires a user-agent that supports redirection from the authorization server (the Microsoft identity platform) back to your application. For example, a web browser, desktop, or mobile application operated by a user to sign in to your app and access their data.

This article describes low-level protocol details required only when manually crafting and issuing raw HTTP requests to execute the flow, which we do not recommend. Instead, use a Microsoft-built and supported authentication library to get security tokens and call protected web APIs in your apps.

Applications that support the auth code flow

Use the auth code flow paired with Proof Key for Code Exchange (PKCE) and OpenID Connect (OIDC) to get access tokens and ID tokens in these types of apps:

Protocol details

The OAuth 2.0 authorization code flow is described in section 4.1 of the OAuth 2.0 specification. Apps using the OAuth 2.0 authorization code flow acquire an access_token to include in requests to resources protected by the Microsoft identity platform (typically APIs). Apps can also request new ID and access tokens for previously authenticated entities by using a refresh mechanism.

This diagram shows a high-level view of the authentication flow:

Diagram shows OAuth authorization code flow. Native app and Web A P I interact by using tokens as described in this article.

Redirect URIs for single-page apps (SPAs)

Redirect URIs for SPAs that use the auth code flow require special configuration.

The spa redirect type is backward-compatible with the implicit flow. Apps currently using the implicit flow to get tokens can move to the spa redirect URI type without issues and continue using the implicit flow. Despite this backward compatibility, we recommend that you use the auth code flow with PKCE for SPAs.

If you attempt to use the authorization code flow without setting up CORS for your redirect URI, you'll see this error in the console:

access to XMLHttpRequest at 'https://login.microsoftonline.com/common/v2.0/oauth2/token' from origin 'yourApp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

If so, visit your app registration and update the redirect URI for your app to use the spa type.

Applications can't use a spa redirect URI with non-SPA flows, for example, native applications or client credential flows. To ensure security and best practices, the Microsoft identity platform returns an error if you attempt to use a spa redirect URI without an Origin header. Similarly, the Microsoft identity platform also prevents the use of client credentials in all flows in the presence of an Origin header, to ensure that secrets aren't used from within the browser.

Request an authorization code

The authorization code flow begins with the client directing the user to the /authorize endpoint. In this example request, the client requests the openid, offline_access, and https://graph.microsoft.com/mail.read permissions from the user.

Some permissions are admin-restricted, for example, writing data to an organization's directory by using Directory.ReadWrite.All. If your application requests access to one of these permissions from an organizational user, the user receives an error message that says they're not authorized to consent to your app's permissions. To request access to admin-restricted scopes, you should request them directly from a Global Administrator. For more information, see Admin-restricted permissions.

Unless specified otherwise, there are no default values for optional parameters. There is, however, default behavior for a request omitting optional parameters. The default behavior is to either sign in the sole current user, show the account picker if there are multiple users, or show the login page if there are no users signed in.

// Line breaks for legibility only

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&response_type=code
&redirect_uri=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttp%2Flocalhost%2Fmyapp%2F
&response_mode=query
&scope=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttps%2Fgraph.microsoft.com%2Fmail.read
&state=12345
&code_challenge=YTFjNjI1OWYzMzA3MTI4ZDY2Njg5M2RkNmVjNDE5YmEyZGRhOGYyM2IzNjdmZWFhMTQ1ODg3NDcxY2Nl
&code_challenge_method=S256
Parameter Required/optional Description
tenant required The {tenant} value in the path of the request can be used to control who can sign into the application. Valid values are common, organizations, consumers, and tenant identifiers. For guest scenarios where you sign a user from one tenant into another tenant, you must provide the tenant identifier to sign them into the resource tenant. For more information, see Endpoints.
client_id required The Application (client) ID that the Microsoft Entra admin center – App registrations experience assigned to your app.
response_type required Must include code for the authorization code flow. Can also include id_token or token if using the hybrid flow.
redirect_uri required The redirect_uri of your app, where authentication responses can be sent and received by your app. It must exactly match one of the redirect URIs you registered in the Microsoft Entra admin center, except it must be URL-encoded. For native and mobile apps, use one of the recommended values: https://login.microsoftonline.com/common/oauth2/nativeclient for apps using embedded browsers or http://localhost for apps that use system browsers.
scope required A space-separated list of scopes that you want the user to consent to. For the /authorize leg of the request, this parameter can cover multiple resources. This value allows your app to get consent for multiple web APIs you want to call.
response_mode recommended Specifies how the identity platform should return the requested token to your app.

Supported values:

- query: Default when requesting an access token. Provides the code as a query string parameter on your redirect URI. The query parameter isn't supported when requesting an ID token by using the implicit flow.
- fragment: Default when requesting an ID token by using the implicit flow. Also supported if requesting only a code.
- form_post: Executes a POST containing the code to your redirect URI. Supported when requesting a code.

state recommended A value included in the request that is also returned in the token response. It can be a string of any content that you wish. A randomly generated unique value is typically used for preventing cross-site request forgery attacks. The value can also encode information about the user's state in the app before the authentication request occurred. For instance, it could encode the page or view they were on.
prompt optional Indicates the type of user interaction that is required. Valid values are login, none, consent, and select_account.

- prompt=login forces the user to enter their credentials on that request, negating single-sign on.
- prompt=none is the opposite. It ensures that the user isn't presented with any interactive prompt. If the request can't be completed silently by using single-sign on, the Microsoft identity platform returns an interaction_required error.
- prompt=consent triggers the OAuth consent dialog after the user signs in, asking the user to grant permissions to the app.
- prompt=select_account interrupts single sign-on providing account selection experience listing all the accounts either in session or any remembered account or an option to choose to use a different account altogether.
login_hint optional You can use this parameter to pre-fill the username and email address field of the sign-in page for the user. Apps can use this parameter during reauthentication, after already extracting the login_hint optional claim from an earlier sign-in.
domain_hint optional If included, the app skips the email-based discovery process that user goes through on the sign-in page, leading to a slightly more streamlined user experience. For example, sending them to their federated identity provider. Apps can use this parameter during reauthentication, by extracting the tid from a previous sign-in.
code_challenge recommended / required Used to secure authorization code grants by using Proof Key for Code Exchange (PKCE). Required if code_challenge_method is included. For more information, see the PKCE RFC. This parameter is now recommended for all application types, both public and confidential clients, and required by the Microsoft identity platform for single page apps using the authorization code flow.
code_challenge_method recommended / required The method used to encode the code_verifier for the code_challenge parameter. This SHOULD be S256, but the spec allows the use of plain if the client can't support SHA256.

If excluded, code_challenge is assumed to be plaintext if code_challenge is included. The Microsoft identity platform supports both plain and S256. For more information, see the PKCE RFC. This parameter is required for single page apps using the authorization code flow.

At this point, the user is asked to enter their credentials and complete the authentication. The Microsoft identity platform also ensures that the user has consented to the permissions indicated in the scope query parameter. If the user hasn't consented to any of those permissions, it asks the user to consent to the required permissions. For more information, see Permissions and consent in the Microsoft identity platform.

Once the user authenticates and grants consent, the Microsoft identity platform returns a response to your app at the indicated redirect_uri, using the method specified in the response_mode parameter.

Successful response

This example shows a successful response using response_mode=query:

GET http://localhost?
code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...
&state=12345
Parameter Description
code The authorization_code that the app requested. The app can use the authorization code to request an access token for the target resource. Authorization codes are short lived. Typically, they expire after about 10 minutes.
state If a state parameter is included in the request, the same value should appear in the response. The app should verify that the state values in the request and response are identical.

You can also receive an ID token if you request one and have the implicit grant enabled in your application registration. This behavior is sometimes referred to as the hybrid flow. It's used by frameworks like ASP.NET.

Error response

Error responses may also be sent to the redirect_uri so the app can handle them appropriately:

GET http://localhost?
error=access_denied
&error_description=the+user+canceled+the+authentication
Parameter Description
error An error code string that can be used to classify types of errors, and to react to errors. This part of the error is provided so that the app can react appropriately to the error, but doesn't explain in depth why an error occurred.
error_description A specific error message that can help a developer identify the cause of an authentication error. This part of the error contains most of the useful information about why the error occurred.

Error codes for authorization endpoint errors

The following table describes the various error codes that can be returned in the error parameter of the error response.

Error Code Description Client Action
invalid_request Protocol error, such as a missing required parameter. Fix and resubmit the request. This error is a development error typically caught during initial testing.
unauthorized_client The client application isn't permitted to request an authorization code. This error usually occurs when the client application isn't registered in Microsoft Entra ID or isn't added to the user's Microsoft Entra tenant. The application can prompt the user with instruction for installing the application and adding it to Microsoft Entra ID.
access_denied Resource owner denied consent The client application can notify the user that it can't continue unless the user consents.
unsupported_response_type The authorization server doesn't support the response type in the request. Fix and resubmit the request. This error is a development error typically caught during initial testing. In the hybrid flow, this error signals that you must enable the ID token implicit grant setting on the client app registration.
server_error The server encountered an unexpected error. Retry the request. These errors can result from temporary conditions. The client application might explain to the user that its response is delayed to a temporary error.
temporarily_unavailable The server is temporarily too busy to handle the request. Retry the request. The client application might explain to the user that its response is delayed because of a temporary condition.
invalid_resource The target resource is invalid because it doesn't exist, Microsoft Entra ID can't find it, or it's not correctly configured. This error indicates the resource, if it exists, hasn't been configured in the tenant. The application can prompt the user with instruction for installing the application and adding it to Microsoft Entra ID.
login_required Too many or no users found. The client requested silent authentication (prompt=none), but a single user couldn't be found. This error may mean there are multiple users active in the session, or no users. This error takes into account the tenant chosen. For example, if there are two Microsoft Entra accounts active and one Microsoft account, and consumers is chosen, silent authentication works.
interaction_required The request requires user interaction. Another authentication step or consent is required. Retry the request without prompt=none.

Request an ID token as well or hybrid flow

To learn who the user is before redeeming an authorization code, it's common for applications to also request an ID token when they request the authorization code. This approach is called the hybrid flow because it mixes OIDC with the OAuth2 authorization code flow.

The hybrid flow is commonly used in web apps to render a page for a user without blocking on code redemption, notably in ASP.NET. Both single-page apps and traditional web apps benefit from reduced latency in this model.

The hybrid flow is the same as the authorization code flow described earlier but with three additions. All of these additions are required to request an ID token: new scopes, a new response_type, and a new nonce query parameter.

// Line breaks for legibility only

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&response_type=code%20id_token
&redirect_uri=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttp%2Flocalhost%2Fmyapp%2F
&response_mode=fragment
&scope=openid%20offline_access%20https%3A%2F%2Frp.liu233w.com%3A443%2Fhttps%2Fgraph.microsoft.com%2Fuser.read
&state=12345
&nonce=abcde
&code_challenge=YTFjNjI1OWYzMzA3MTI4ZDY2Njg5M2RkNmVjNDE5YmEyZGRhOGYyM2IzNjdmZWFhMTQ1ODg3NDcxY2Nl
&code_challenge_method=S256
Updated Parameter Required/optional Description
response_type required The addition of id_token indicates to the server that the application would like an ID token in the response from the /authorize endpoint.
scope required For ID tokens, this parameter must be updated to include the ID token scopes: openid and optionally profile and email.
nonce required A value included in the request, generated by the app, that is included in the resulting id_token as a claim. The app can then verify this value to mitigate token replay attacks. The value is typically a randomized, unique string that can be used to identify the origin of the request.
response_mode recommended Specifies the method that should be used to send the resulting token back to your app. Default value is query for just an authorization code, but fragment if the request includes an id_token response_type as specified in the OpenID spec. We recommend apps use form_post, especially when using http://localhost as a redirect URI.

The use of fragment as a response mode causes issues for web apps that read the code from the redirect. Browsers don't pass the fragment to the web server. In these situations, apps should use the form_post response mode to ensure that all data is sent to the server.

Successful response

This example shows a successful response using response_mode=fragment:

GET https://login.microsoftonline.com/common/oauth2/nativeclient#
code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...
&id_token=eYj...
&state=12345
Parameter Description
code The authorization code that the app requested. The app can use the authorization code to request an access token for the target resource. Authorization codes are short lived, typically expiring after about 10 minutes.
id_token An ID token for the user, issued by using the implicit grant. Contains a special c_hash claim that is the hash of the code in the same request.
state If a state parameter is included in the request, the same value should appear in the response. The app should verify that the state values in the request and response are identical.

Redeem a code for an access token

All confidential clients have a choice of using client secrets or certificate credentials. Symmetric shared secrets are generated by the Microsoft identity platform. Certificate credentials are asymmetric keys uploaded by the developer. For more information, see Microsoft identity platform application authentication certificate credentials.

For best security, we recommend using certificate credentials. Public clients, which include native applications and single page apps, must not use secrets or certificates when redeeming an authorization code. Always ensure that your redirect URIs include the type of application and are unique.

Request an access token with a client_secret

Now that you've acquired an authorization_code and have been granted permission by the user, you can redeem the code for an access_token to the resource. Redeem the code by sending a POST request to the /token endpoint:

// Line breaks for legibility only

POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=11112222-bbbb-3333-cccc-4444dddd5555
&scope=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttps%2Fgraph.microsoft.com%2Fmail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttp%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong 
&client_secret=sampleCredentia1s    // NOTE: Only required for web apps. This secret needs to be URL-Encoded.
Parameter Required/optional Description
tenant required The {tenant} value in the path of the request can be used to control who can sign into the application. Valid values are common, organizations, consumers, and tenant identifiers. For more information, see Endpoints.
client_id required The Application (client) ID that the Microsoft Entra admin center – App registrations page assigned to your app.
scope optional A space-separated list of scopes. The scopes must all be from a single resource, along with OIDC scopes (profile, openid, email). For more information, see Permissions and consent in the Microsoft identity platform. This parameter is a Microsoft extension to the authorization code flow, intended to allow apps to declare the resource they want the token for during token redemption.
code required The authorization_code that you acquired in the first leg of the flow.
redirect_uri required The same redirect_uri value that was used to acquire the authorization_code.
grant_type required Must be authorization_code for the authorization code flow.
code_verifier recommended The same code_verifier that was used to obtain the authorization_code. Required if PKCE was used in the authorization code grant request. For more information, see the PKCE RFC.
client_secret required for confidential web apps The application secret that you created in the app registration portal for your app. Don't use the application secret in a native app or single page app because a client_secret can't be reliably stored on devices or web pages. It's required for web apps and web APIs, which can store the client_secret securely on the server side. Like all parameters here, the client secret must be URL-encoded before being sent. This step is done by the SDK. For more information on URI encoding, see the URI Generic Syntax specification. The Basic auth pattern of instead providing credentials in the Authorization header, per RFC 6749 is also supported.

Request an access token with a certificate credential

// Line breaks for legibility only
POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttps%2Fgraph.microsoft.com%2Fmail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttp%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
Parameter Required/optional Description
tenant required The {tenant} value in the path of the request can be used to control who can sign into the application. Valid values are common, organizations, consumers, and tenant identifiers. For more detail, see Endpoints.
client_id required The Application (client) ID that the Microsoft Entra admin center – App registrations page assigned to your app.
scope optional A space-separated list of scopes. The scopes must all be from a single resource, along with OIDC scopes (profile, openid, email). For more information, see permissions, consent, and scopes. This parameter is a Microsoft extension to the authorization code flow. This extension allows apps to declare the resource they want the token for during token redemption.
code required The authorization_code that you acquired in the first leg of the flow.
redirect_uri required The same redirect_uri value that was used to acquire the authorization_code.
grant_type required Must be authorization_code for the authorization code flow.
code_verifier recommended The same code_verifier that was used to obtain the authorization_code. Required if PKCE was used in the authorization code grant request. For more information, see the PKCE RFC.
client_assertion_type required for confidential web apps The value must be set to urn:ietf:params:oauth:client-assertion-type:jwt-bearer to use a certificate credential.
client_assertion required for confidential web apps An assertion, which is a JSON web token (JWT), that you need to create and sign with the certificate you registered as credentials for your application. Read about certificate credentials to learn how to register your certificate and the format of the assertion.

The parameters are same as the request by shared secret except that the client_secret parameter is replaced by two parameters: a client_assertion_type and client_assertion.

Successful response

This example shows a successful token response:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
    "token_type": "Bearer",
    "expires_in": 3599,
    "scope": "https%3A%2F%2Frp.liu233w.com%3A443%2Fhttps%2Fgraph.microsoft.com%2Fmail.read",
    "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD..."
}
Parameter Description
access_token The requested access token. The app can use this token to authenticate to the secured resource, such as a web API.
token_type Indicates the token type value. The only type that Microsoft Entra ID supports is Bearer.
expires_in How long the access token is valid, in seconds.
scope The scopes that the access_token is valid for. Optional. This parameter is non-standard and, if omitted, the token is for the scopes requested on the initial leg of the flow.
refresh_token An OAuth 2.0 refresh token. The app can use this token to acquire other access tokens after the current access token expires. Refresh tokens are long-lived. They can maintain access to resources for extended periods. For more detail on refreshing an access token, refer to Refresh the access token later in this article.
Note: Only provided if offline_access scope was requested.
id_token A JSON Web Token. The app can decode the segments of this token to request information about the user who signed in. The app can cache the values and display them, and confidential clients can use this token for authorization. For more information about id_tokens, see the id_token reference.
Note: Only provided if openid scope was requested.

Error response

This example is an Error response:

{
  "error": "invalid_scope",
  "error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://foo.microsoft.com/mail.read is not valid.\r\nTrace ID: 0000aaaa-11bb-cccc-dd22-eeeeee333333\r\nCorrelation ID: aaaa0000-bb11-2222-33cc-444444dddddd\r\nTimestamp: 2016-01-09 02:02:12Z",
  "error_codes": [
    70011
  ],
  "timestamp": "2016-01-09 02:02:12Z",
  "trace_id": "0000aaaa-11bb-cccc-dd22-eeeeee333333",
  "correlation_id": "aaaa0000-bb11-2222-33cc-444444dddddd"
}
Parameter Description
error An error code string that can be used to classify types of errors, and to react to errors.
error_description A specific error message that can help a developer identify the cause of an authentication error.
error_codes A list of STS-specific error codes that can help in diagnostics.
timestamp The time at which the error occurred.
trace_id A unique identifier for the request that can help in diagnostics.
correlation_id A unique identifier for the request that can help in diagnostics across components.

Error codes for token endpoint errors

Error Code Description Client Action
invalid_request Protocol error, such as a missing required parameter. Fix the request or app registration and resubmit the request.
invalid_grant The authorization code or PKCE code verifier is invalid or has expired. Try a new request to the /authorize endpoint and verify that the code_verifier parameter was correct.
unauthorized_client The authenticated client isn't authorized to use this authorization grant type. This error usually occurs when the client application isn't registered in Microsoft Entra ID or isn't added to the user's Microsoft Entra tenant. The application can prompt the user with instruction for installing the application and adding it to Microsoft Entra ID.
invalid_client Client authentication failed. The client credentials aren't valid. To fix, the Application Administrator updates the credentials.
unsupported_grant_type The authorization server doesn't support the authorization grant type. Change the grant type in the request. This type of error should occur only during development and be detected during initial testing.
invalid_resource The target resource is invalid because it doesn't exist, Microsoft Entra ID can't find it, or it's not correctly configured. This code indicates the resource, if it exists, hasn't been configured in the tenant. The application can prompt the user with instruction for installing the application and adding it to Microsoft Entra ID.
interaction_required Non-standard, as the OIDC specification calls for this code only on the /authorize endpoint. The request requires user interaction. For example, another authentication step is required. Retry the /authorize request with the same scopes.
temporarily_unavailable The server is temporarily too busy to handle the request. Retry the request after a small delay. The client application might explain to the user that its response is delayed because of a temporary condition.
consent_required The request requires user consent. This error is non-standard. It's usually only returned on the /authorize endpoint per OIDC specifications. Returned when a scope parameter was used on the code redemption flow that the client app doesn't have permission to request. The client should send the user back to the /authorize endpoint with the correct scope to trigger consent.
invalid_scope The scope requested by the app is invalid. Update the value of the scope parameter in the authentication request to a valid value.

Note

Single page apps may receive an invalid_request error indicating that cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. This indicates that the redirect URI used to request the token has not been marked as a spa redirect URI. Review the application registration steps on how to enable this flow.

Use the access token

Now that you have successfully acquired an access_token, you can use the token in requests to web APIs by including it in the Authorization header:

GET /v1.0/me/messages
Host: https://graph.microsoft.com
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...

Refresh the access token

Access tokens are short lived. Refresh them after they expire to continue accessing resources. You can do so by submitting another POST request to the /token endpoint. Provide the refresh_token instead of the code. Refresh tokens are valid for all permissions that your client has already received consent for. For example, a refresh token issued on a request for scope=mail.read can be used to request a new access token for scope=api://contoso.com/api/UseResource.

Refresh tokens for web apps and native apps don't have specified lifetimes. Typically, the lifetimes of refresh tokens are relatively long. However, in some cases, refresh tokens expire, are revoked, or lack sufficient privileges for the action. Your application needs to expect and handle errors returned by the token issuance endpoint. Single page apps get a token with a 24-hour lifetime, requiring a new authentication every day. This action can be done silently in an iframe when third-party cookies are enabled. It must be done in a top-level frame, either full page navigation or a pop-up window, in browsers without third-party cookies, such as Safari.

Refresh tokens aren't revoked when used to acquire new access tokens. You're expected to discard the old refresh token. The OAuth 2.0 spec says: "The authorization server MAY issue a new refresh token, in which case the client MUST discard the old refresh token and replace it with the new refresh token. The authorization server MAY revoke the old refresh token after issuing a new refresh token to the client."

Important

For refresh tokens sent to a redirect URI registered as spa, the refresh token expires after 24 hours. Additional refresh tokens acquired using the initial refresh token carries over that expiration time, so apps must be prepared to re-run the authorization code flow using an interactive authentication to get a new refresh token every 24 hours. Users do not have to enter their credentials, and usually don't even see any user experience, just a reload of your application. The browser must visit the login page in a top level frame in order to see the login session. This is due to privacy features in browsers that block third party cookies.

// Line breaks for legibility only

POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=https%3A%2F%2Frp.liu233w.com%3A443%2Fhttps%2Fgraph.microsoft.com%2Fmail.read
&refresh_token=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq...
&grant_type=refresh_token
&client_secret=sampleCredentia1s    // NOTE: Only required for web apps. This secret needs to be URL-Encoded
Parameter Type Description
tenant required The {tenant} value in the path of the request can be used to control who can sign into the application. Valid values are common, organizations, consumers, and tenant identifiers. For more information, see Endpoints.
client_id required The Application (client) ID that the Microsoft Entra admin center – App registrations experience assigned to your app.
grant_type required Must be refresh_token for this leg of the authorization code flow.
scope optional A space-separated list of scopes. The scopes requested in this leg must be equivalent to or a subset of the scopes requested in the original authorization_code request leg. If the scopes specified in this request span multiple resource server, then the Microsoft identity platform returns a token for the resource specified in the first scope. For more information, see Permissions and consent in the Microsoft identity platform.
refresh_token required The refresh_token that you acquired in the second leg of the flow.
client_secret required for web apps The application secret that you created in the app registration portal for your app. It shouldn't be used in a native app, because a client_secret can't be reliably stored on devices. It's required for web apps and web APIs, which can store the client_secret securely on the server side. This secret needs to be URL-Encoded. For more information, see the URI Generic Syntax specification.

Successful response

This example shows a successful token response:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
    "token_type": "Bearer",
    "expires_in": 3599,
    "scope": "https%3A%2F%2Frp.liu233w.com%3A443%2Fhttps%2Fgraph.microsoft.com%2Fmail.read",
    "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD..."
}
Parameter Description
access_token The requested access token. The app can use this token to authenticate to the secured resource, such as a web API.
token_type Indicates the token type value. The only type that Microsoft Entra ID supports is Bearer.
expires_in How long the access token is valid, in seconds.
scope The scopes that the access_token is valid for.
refresh_token A new OAuth 2.0 refresh token. Replace the old refresh token with this newly acquired refresh token to ensure your refresh tokens remain valid for as long as possible.
Note: Only provided if offline_access scope was requested.
id_token An unsigned JSON Web Token. The app can decode the segments of this token to request information about the user who signed in. The app can cache the values and display them, but it shouldn't rely on them for any authorization or security boundaries. For more information about id_token, see the Microsoft identity platform ID tokens.
Note: Only provided if openid scope was requested.

Warning

Don't attempt to validate or read tokens for any API you don't own, including the tokens in this example, in your code. Tokens for Microsoft services can use a special format that will not validate as a JWT, and may also be encrypted for consumer (Microsoft account) users. While reading tokens is a useful debugging and learning tool, do not take dependencies on this in your code or assume specifics about tokens that aren't for an API you control.

Error response

{
  "error": "invalid_scope",
  "error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://foo.microsoft.com/mail.read is not valid.\r\nTrace ID: 0000aaaa-11bb-cccc-dd22-eeeeee333333\r\nCorrelation ID: aaaa0000-bb11-2222-33cc-444444dddddd\r\nTimestamp: 2016-01-09 02:02:12Z",
  "error_codes": [
    70011
  ],
  "timestamp": "2016-01-09 02:02:12Z",
  "trace_id": "0000aaaa-11bb-cccc-dd22-eeeeee333333",
  "correlation_id": "aaaa0000-bb11-2222-33cc-444444dddddd"
}
Parameter Description
error An error code string that can be used to classify types of errors, and to react to errors.
error_description A specific error message that can help a developer identify the root cause of an authentication error.
error_codes A list of STS-specific error codes that can help in diagnostics.
timestamp The time at which the error occurred.
trace_id A unique identifier for the request that can help in diagnostics.
correlation_id A unique identifier for the request that can help in diagnostics across components.

For a description of the error codes and the recommended client action, see Error codes for token endpoint errors.

Next steps