OAuth 2.0 client credentials flow on the Microsoft identity platform - Microsoft identity platform (2024)

  • Article

The OAuth 2.0 client credentials grant flow permits a web service (confidential client) to use its own credentials, instead of impersonating a user, to authenticate when calling another web service. The grant specified in RFC 6749, sometimes called two-legged OAuth, can be used to access web-hosted resources by using the identity of an application. This type is commonly used for server-to-server interactions that must run in the background, without immediate interaction with a user, and is often referred to as daemons or service accounts.

In the client credentials flow, permissions are granted directly to the application itself by an administrator. When the app presents a token to a resource, the resource enforces that the app itself has authorization to perform an action since there is no user involved in the authentication. This article covers both the steps needed to:

  • Authorize an application to call an API
  • How to get the tokens needed to call that API.

This article describes how to program directly against the protocol in your application. When possible, we recommend you use the supported Microsoft Authentication Libraries (MSAL) instead to acquire tokens and call secured web APIs. You can also refer to the sample apps that use MSAL. As a side note, refresh tokens will never be granted with this flow as client_id and client_secret (which would be required to obtain a refresh token) can be used to obtain an access token instead.

For a higher level of assurance, the Microsoft identity platform also allows the calling service to authenticate using a certificate or federated credential instead of a shared secret. Because the application's own credentials are being used, these credentials must be kept safe. Never publish that credential in your source code, embed it in web pages, or use it in a widely distributed native application.

Protocol diagram

The entire client credentials flow looks similar to the following diagram. We describe each of the steps later in this article.

OAuth 2.0 client credentials flow on the Microsoft identity platform - Microsoft identity platform (1)

Get direct authorization

An app typically receives direct authorization to access a resource in one of two ways:

  • Through an access control list (ACL) at the resource
  • Through application permission assignment in Microsoft Entra ID

These two methods are the most common in Microsoft Entra ID and we recommend them for clients and resources that perform the client credentials flow. A resource can also choose to authorize its clients in other ways. Each resource server can choose the method that makes the most sense for its application.

Access control lists

A resource provider might enforce an authorization check based on a list of application (client) IDs that it knows and grants a specific level of access to. When the resource receives a token from the Microsoft identity platform, it can decode the token and extract the client's application ID from the appid and iss claims. Then it compares the application against an access control list (ACL) that it maintains. The ACL's granularity and method might vary substantially between resources.

A common use case is to use an ACL to run tests for a web application or for a web API. The web API might grant only a subset of full permissions to a specific client. To run end-to-end tests on the API, you can create a test client that acquires tokens from the Microsoft identity platform and then sends them to the API. The API then checks the ACL for the test client's application ID for full access to the API's entire functionality. If you use this kind of ACL, be sure to validate not only the caller's appid value but also validate that the iss value of the token is trusted.

This type of authorization is common for daemons and service accounts that need to access data owned by consumer users who have personal Microsoft accounts. For data owned by organizations, we recommend that you get the necessary authorization through application permissions.

Controlling tokens without the roles claim

In order to enable this ACL-based authorization pattern, Microsoft Entra ID doesn't require that applications be authorized to get tokens for another application. Thus, app-only tokens can be issued without a roles claim. Applications that expose APIs must implement permission checks in order to accept tokens.

If you'd like to prevent applications from getting role-less app-only access tokens for your application, ensure that assignment requirements are enabled for your app. This will block users and applications without assigned roles from being able to get a token for this application.

Application permissions

Instead of using ACLs, you can use APIs to expose a set of application permissions. These are granted to an application by an organization's administrator, and can be used only to access data owned by that organization and its employees. For example, Microsoft Graph exposes several application permissions to do the following:

  • Read mail in all mailboxes
  • Read and write mail in all mailboxes
  • Send mail as any user
  • Read directory data

To use app roles (application permissions) with your own API (as opposed to Microsoft Graph), you must first expose the app roles in the API's app registration in the Microsoft Entra admin center. Then, configure the required app roles by selecting those permissions in your client application's app registration. If you haven't exposed any app roles in your API's app registration, you won't be able to specify application permissions to that API in your client application's app registration in the Microsoft Entra admin center.

When authenticating as an application (as opposed to with a user), you can't use delegated permissions because there is no user for your app to act on behalf of. You must use application permissions, also known as app roles, that are granted by an admin or by the API's owner.

For more information about application permissions, see Permissions and consent.

Recommended: Sign the admin into your app to have app roles assigned

Typically, when you build an application that uses application permissions, the app requires a page or view on which the admin approves the app's permissions. This page can be part of the app's sign-in flow, part of the app's settings, or a dedicated connect flow. It often makes sense for the app to show this connect view only after a user has signed in with a work or school Microsoft account.

If you sign the user into your app, you can identify the organization to which the user belongs to before you ask the user to approve the application permissions. Although not strictly necessary, it can help you create a more intuitive experience for your users. To sign the user in, follow the Microsoft identity platform protocol tutorials.

Request the permissions from a directory admin

When you're ready to request permissions from the organization's admin, you can redirect the user to the Microsoft identity platform admin consent endpoint.

// Line breaks are for legibility only.GET https://login.microsoftonline.com/{tenant}/adminconsent?client_id=00001111-aaaa-2222-bbbb-3333cccc4444&state=12345&redirect_uri=http://localhost/myapp/permissions

Pro tip: Try pasting the following request in a browser.

https://login.microsoftonline.com/common/adminconsent?client_id=00001111-aaaa-2222-bbbb-3333cccc4444&state=12345&redirect_uri=http://localhost/myapp/permissions
ParameterConditionDescription
tenantRequiredThe directory tenant that you want to request permission from. This can be in GUID or friendly name format. If you don't know which tenant the user belongs to and you want to let them sign in with any tenant, use common.
client_idRequiredThe Application (client) ID that the Microsoft Entra admin center – App registrations experience assigned to your app.
redirect_uriRequiredThe redirect URI where you want the response to be sent for your app to handle. It must exactly match one of the redirect URIs that you registered in the portal, except that it must be URL-encoded, and it can have additional path segments.
stateRecommendedA value that's included in the request that's also returned in the token response. It can be a string of any content that you want. The state is used to encode information about the user's state in the app before the authentication request occurred, such as the page or view they were on.

At this point, Microsoft Entra ID enforces that only a tenant administrator can sign in to complete the request. The administrator will be asked to approve all the direct application permissions that you have requested for your app in the app registration portal.

Successful response

If the admin approves the permissions for your application, the successful response looks like this:

GET http://localhost/myapp/permissions?tenant=aaaabbbb-0000-cccc-1111-dddd2222eeee&state=state=12345&admin_consent=True
ParameterDescription
tenantThe directory tenant that granted your application the permissions that it requested, in GUID format.
stateA value that is included in the request that also is returned in the token response. It can be a string of any content that you want. The state is used to encode information about the user's state in the app before the authentication request occurred, such as the page or view they were on.
admin_consentSet to True.
Error response

If the admin does not approve the permissions for your application, the failed response looks like this:

GET http://localhost/myapp/permissions?error=permission_denied&error_description=The+admin+canceled+the+request
ParameterDescription
errorAn error code string that you can use to classify types of errors, and which you can use to react to errors.
error_descriptionA specific error message that can help you identify the root cause of an error.

After you've received a successful response from the app provisioning endpoint, your app has gained the direct application permissions that it requested. Now you can request a token for the resource that you want.

Get a token

After you've acquired the necessary authorization for your application, proceed with acquiring access tokens for APIs. To get a token by using the client credentials grant, send a POST request to the /token Microsoft identity platform. There are a few different cases:

  • Access token request with a shared secret
  • Access token request with a certificate
  • Access token request with a federated credential
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 //Line breaks for clarityHost: login.microsoftonline.com:443Content-Type: application/x-www-form-urlencodedclient_id=00001111-aaaa-2222-bbbb-3333cccc4444&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=qWgdYAmab0YSkuL1qKv5bPX&grant_type=client_credentials
# Replace {tenant} with your tenant!curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=00001111-aaaa-2222-bbbb-3333cccc4444&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=A1bC2dE3f...&grant_type=client_credentials' 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token'
ParameterConditionDescription
tenantRequiredThe directory tenant the application plans to operate against, in GUID or domain-name format.
client_idRequiredThe application ID that's assigned to your app. You can find this information in the portal where you registered your app.
scopeRequiredThe value passed for the scope parameter in this request should be the resource identifier (application ID URI) of the resource you want, affixed with the .default suffix. All scopes included must be for a single resource. Including scopes for multiple resources will result in an error.
For the Microsoft Graph example, the value is https://graph.microsoft.com/.default. This value tells the Microsoft identity platform that of all the direct application permissions you have configured for your app, the endpoint should issue a token for the ones associated with the resource you want to use. To learn more about the /.default scope, see the consent documentation.
client_secretRequiredThe client secret that you generated for your app in the app registration portal. The client secret must be URL-encoded before being sent. The Basic auth pattern of instead providing credentials in the Authorization header, per RFC 6749 is also supported.
grant_typeRequiredMust be set to client_credentials.

Second case: Access token request with a certificate

POST /{tenant}/oauth2/v2.0/token HTTP/1.1 // Line breaks for clarityHost: login.microsoftonline.com:443Content-Type: application/x-www-form-urlencodedscope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_id=11112222-bbbb-3333-cccc-4444dddd5555&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg&grant_type=client_credentials
ParameterConditionDescription
tenantRequiredThe directory tenant the application plans to operate against, in GUID or domain-name format.
client_idRequiredThe application (client) ID that's assigned to your app.
scopeRequiredThe value passed for the scope parameter in this request should be the resource identifier (application ID URI) of the resource you want, affixed with the .default suffix. All scopes included must be for a single resource. Including scopes for multiple resources will result in an error.
For the Microsoft Graph example, the value is https://graph.microsoft.com/.default. This value tells the Microsoft identity platform that of all the direct application permissions you have configured for your app, the endpoint should issue a token for the ones associated with the resource you want to use. To learn more about the /.default scope, see the consent documentation.
client_assertion_typeRequiredThe value must be set to urn:ietf:params:oauth:client-assertion-type:jwt-bearer.
client_assertionRequiredAn assertion (a JSON web token) 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.
grant_typeRequiredMust be set to client_credentials.

The parameters for the certificate-based request differ in only one way from the shared secret-based request: the client_secret parameter is replaced by the client_assertion_type and client_assertion parameters.

Third case: Access token request with a federated credential

POST /{tenant}/oauth2/v2.0/token HTTP/1.1 // Line breaks for clarityHost: login.microsoftonline.com:443Content-Type: application/x-www-form-urlencodedscope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_id=11112222-bbbb-3333-cccc-4444dddd5555&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg&grant_type=client_credentials
ParameterConditionDescription
client_assertionRequiredAn assertion (a JWT, or JSON web token) that your application gets from another identity provider outside of Microsoft identity platform, like Kubernetes. The specifics of this JWT must be registered on your application as a federated identity credential. Read about workload identity federation to learn how to setup and use assertions generated from other identity providers.

Everything in the request is the same as the certificate-based flow, with the crucial exception of the source of the client_assertion. In this flow, your application does not create the JWT assertion itself. Instead, your app uses a JWT created by another identity provider. This is called workload identity federation, where your apps identity in another identity platform is used to acquire tokens inside the Microsoft identity platform. This is best suited for cross-cloud scenarios, such as hosting your compute outside Azure but accessing APIs protected by Microsoft identity platform. For information about the required format of JWTs created by other identity providers, read about the assertion format.

Successful response

A successful response from any method looks like this:

{ "token_type": "Bearer", "expires_in": 3599, "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBP..."}
ParameterDescription
access_tokenThe requested access token. The app can use this token to authenticate to the secured resource, such as to a web API.
token_typeIndicates the token type value. The only type that the Microsoft identity platform supports is bearer.
expires_inThe amount of time that an access token is valid (in seconds).

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

An error response (400 Bad Request) looks like this:

{ "error": "invalid_scope", "error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://foo.microsoft.com/.default 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": "YYYY-MM-DD HH:MM:SSZ", "trace_id": "0000aaaa-11bb-cccc-dd22-eeeeee333333", "correlation_id": "aaaa0000-bb11-2222-33cc-444444dddddd"}
ParameterDescription
errorAn error code string that you can use to classify types of errors that occur, and to react to errors.
error_descriptionA specific error message that might help you identify the root cause of an authentication error.
error_codesA list of STS-specific error codes that might help with diagnostics.
timestampThe time when the error occurred.
trace_idA unique identifier for the request to help with diagnostics.
correlation_idA unique identifier for the request to help with diagnostics across components.

Use a token

Now that you've acquired a token, use the token to make requests to the resource. When the token expires, repeat the request to the /token endpoint to acquire a fresh access token.

GET /v1.0/users HTTP/1.1Host: graph.microsoft.com:443Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...

Try the following command in your terminal, ensuring to replace the token with your own.

curl -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG..." 'https://graph.microsoft.com/v1.0/users'

Code samples and other documentation

Read the client credentials overview documentation from the Microsoft Authentication Library

SamplePlatformDescription
active-directory-dotnetcore-daemon-v2.NET 6.0+An ASP.NET Core application that displays the users of a tenant querying the Microsoft Graph using the identity of the application, instead of on behalf of a user. The sample also illustrates the variation using certificates for authentication.
active-directory-dotnet-daemon-v2ASP.NET MVCA web application that syncs data from the Microsoft Graph using the identity of the application, instead of on behalf of a user.
ms-identity-javascript-nodejs-consoleNode.js ConsoleA Node.js application that displays the users of a tenant by querying the Microsoft Graph using the identity of the application
OAuth 2.0 client credentials flow on the Microsoft identity platform - Microsoft identity platform (2024)
Top Articles
IonQ Poised for Aggressive Commercial Growth in 2023 Sets Date to Report on Momentum and Fourth Quarter 2022 Financial Results
Why Do Dogs Eat Grass?
Netronline Taxes
Victor Spizzirri Linkedin
Warren Ohio Craigslist
Trevor Goodwin Obituary St Cloud
12 Rue Gotlib 21St Arrondissem*nt
Practical Magic 123Movies
Bustle Daily Horoscope
Rainfall Map Oklahoma
What’s the Difference Between Cash Flow and Profit?
Used Wood Cook Stoves For Sale Craigslist
Everything You Need to Know About Holly by Stephen King
Zürich Stadion Letzigrund detailed interactive seating plan with seat & row numbers | Sitzplan Saalplan with Sitzplatz & Reihen Nummerierung
Leeks — A Dirty Little Secret (Ingredient)
Craiglist Kpr
使用 RHEL 8 时的注意事项 | Red Hat Product Documentation
Uta Kinesiology Advising
The Blind Showtimes Near Amc Merchants Crossing 16
Stoney's Pizza & Gaming Parlor Danville Menu
67-72 Chevy Truck Parts Craigslist
Www Va Lottery Com Result
2000 Ford F-150 for sale - Scottsdale, AZ - craigslist
Margaret Shelton Jeopardy Age
10 Best Quotes From Venom (2018)
WOODSTOCK CELEBRATES 50 YEARS WITH COMPREHENSIVE 38-CD DELUXE BOXED SET | Rhino
County Cricket Championship, day one - scores, radio commentary & live text
R/Orangetheory
Donald Trump Assassination Gold Coin JD Vance USA Flag President FIGHT CIA FBI • $11.73
Emiri's Adventures
Wbli Playlist
Tenant Vs. Occupant: Is There Really A Difference Between Them?
Oreillys Federal And Evans
AsROck Q1900B ITX und Ramverträglichkeit
Build-A-Team: Putting together the best Cathedral basketball team
Toonily The Carry
World History Kazwire
Frcp 47
Metro Pcs Forest City Iowa
Differential Diagnosis
Foxxequeen
Gli italiani buttano sempre più cibo, quasi 7 etti a settimana (a testa)
What is a lifetime maximum benefit? | healthinsurance.org
New Zero Turn Mowers For Sale Near Me
De boeken van Val McDermid op volgorde
Roller Znen ZN50QT-E
Diesel Technician/Mechanic III - Entry Level - transportation - job employment - craigslist
Epower Raley's
What Responsibilities Are Listed In Duties 2 3 And 4
Ranking 134 college football teams after Week 1, from Georgia to Temple
Latest Posts
Article information

Author: Dong Thiel

Last Updated:

Views: 6436

Rating: 4.9 / 5 (79 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Dong Thiel

Birthday: 2001-07-14

Address: 2865 Kasha Unions, West Corrinne, AK 05708-1071

Phone: +3512198379449

Job: Design Planner

Hobby: Graffiti, Foreign language learning, Gambling, Metalworking, Rowing, Sculling, Sewing

Introduction: My name is Dong Thiel, I am a brainy, happy, tasty, lively, splendid, talented, cooperative person who loves writing and wants to share my knowledge and understanding with you.