Choose a Microsoft Graph authentication provider based on scenario
Authentication providers implement the code required to acquire a token using the Microsoft Authentication Library (MSAL); handle a number of potential errors for cases like incremental consent, expired passwords, and conditional access; and then set the HTTP request authorization header. The following table lists the set of providers that match the scenarios for different application types.
Scenario | Flow/Grant | Audience | Provider |
---|---|---|---|
Single Page App | Authorization Code with PKCE | Delegated Consumer/Org | Authorization code provider |
Web App that calls web APIs | |||
Authorization Code | Delegated Consumer/Org | Authorization code provider | |
Client Credentials | App Only | Client credentials provider | |
Web API that calls web APIs | |||
On Behalf Of | Delegated Consumer/Org | On-behalf-of provider | |
Client Credentials | App Only | Client credentials provider | |
Desktop app that calls web APIs | |||
Interactive | Delegated Consumer/Org | Interactive provider | |
Integrated Windows | Delegated Org | Integrated Windows provider | |
Resource Owner | Delegated Org | Username/password provider | |
Device Code | Delegated Org | Device code provider | |
Daemon app | |||
Client Credentials | App Only | Client credentials provider | |
Mobile app that calls web APIs | |||
Interactive | Delegated Consumer/Org | Interactive provider |
Note
The following code snippets were written with the latest versions of their respective SDKs. If you encounter compiler errors with these snippets, make sure you have the latest versions. The authentication providers used are provided by the following Azure Identity libraries:
- .NET developers need to add the Azure.Identity package.
- JavaScript developers need to add the @azure/identity library.
- Java and Android developers need to add the azure-identity library.
Authorization code provider
The authorization code flow enables native and web apps to securely obtain tokens in the name of the user. To learn more, see Microsoft identity platform and OAuth 2.0 authorization code flow.
var scopes = new[] { "User.Read" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";
// For authorization code flow, the user signs into the Microsoft
// identity platform, and the browser is redirected back to your app
// with an authorization code in the query parameters
var authorizationCode = "AUTH_CODE_FROM_REDIRECT";
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://learn.microsoft.com/dotnet/api/azure.identity.authorizationcodecredential
var authCodeCredential = new AuthorizationCodeCredential(
tenantId, clientId, clientSecret, authorizationCode, options);
var graphClient = new GraphServiceClient(authCodeCredential, scopes);
Client credentials provider
The client credential flow enables service applications to run without user interaction. Access is based on the identity of the application. For more information, see Microsoft identity platform and the OAuth 2.0 client credentials flow.
Using a client secret
// The client credentials flow requires that you request the
// /.default scope, and preconfigure your permissions on the
// app registration in Azure. An administrator must grant consent
// to those permissions beforehand.
var scopes = new[] { "https://graph.microsoft.com/.default" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://learn.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
Using a client certificate
var scopes = new[] { "https://graph.microsoft.com/.default" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientCertificate = new X509Certificate2("MyCertificate.pfx");
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://learn.microsoft.com/dotnet/api/azure.identity.clientcertificatecredential
var clientCertCredential = new ClientCertificateCredential(
tenantId, clientId, clientCertificate, options);
var graphClient = new GraphServiceClient(clientCertCredential, scopes);
On-behalf-of provider
The on-behalf-of flow is applicable when your application calls a service/web API which in turns calls the Microsoft Graph API. Learn more by reading Microsoft identity platform and OAuth 2.0 On-Behalf-Of flow
The Azure.Identity
package does not support the on-behalf-of flow as of version 1.4.0. Instead create a custom authentication provider using MSAL.
var scopes = new[] { "User.Read" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";
// using Azure.Identity;
var options = new OnBehalfOfCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// This is the incoming token to exchange using on-behalf-of flow
var oboToken = "JWT_TOKEN_TO_EXCHANGE";
var onBehalfOfCredential = new OnBehalfOfCredential(tenantId, clientId, clientSecret, oboToken, options);
var graphClient = new GraphServiceClient(onBehalfOfCredential,scopes);
Implicit provider
Implicit Authentication flow is not recommended due to its disadvantages. Public clients such as native apps and JavaScript apps should now use the authorization code flow with the PKCE extension instead. Reference.
Device code provider
The device code flow enables sign in to devices by way of another device. For details, see Microsoft identity platform and the OAuth 2.0 device code flow.
var scopes = new[] { "User.Read" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Value from app registration
var clientId = "YOUR_CLIENT_ID";
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// Callback function that receives the user prompt
// Prompt contains the generated device code that use must
// enter during the auth process in the browser
Func<DeviceCodeInfo, CancellationToken, Task> callback = (code, cancellation) => {
Console.WriteLine(code.Message);
return Task.FromResult(0);
};
// https://learn.microsoft.com/dotnet/api/azure.identity.devicecodecredential
var deviceCodeCredential = new DeviceCodeCredential(
callback, tenantId, clientId, options);
var graphClient = new GraphServiceClient(deviceCodeCredential, scopes);
Integrated Windows provider
The integrated Windows flow provides a way for Windows computers to silently acquire an access token when they are domain joined. For details, see Integrated Windows authentication.
The Azure.Identity
package does not currently support Windows integrated authentication. Instead create a custom authentication provider using MSAL.
public class TokenProvider : IAccessTokenProvider
{
private readonly IPublicClientApplication publicClientApplication;
public TokenProvider(string clientId, string tenantId)
{
publicClientApplication = PublicClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantId)
.Build();
AllowedHostsValidator = new AllowedHostsValidator();
}
public async Task<string> GetAuthorizationTokenAsync(Uri uri, Dictionary<string, object> additionalAuthenticationContext = default,
CancellationToken cancellationToken = default)
{
var scopes = new[] { "User.Read" };
var result = await publicClientApplication.AcquireTokenByIntegratedWindowsAuth(scopes).ExecuteAsync(); ;
// get the token and return it in your own way
return Task.FromResult(result.A);
}
public AllowedHostsValidator AllowedHostsValidator { get; }
}
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Value from app registration
var clientId = "YOUR_CLIENT_ID";
var authenticationProvider = new BaseBearerTokenAuthenticationProvider(new TokenProvider(clientId,tenantId));
var graphServiceClient = new GraphServiceClient(authenticationProvider);
Interactive provider
The interactive flow is used by mobile applications (Xamarin and UWP) and desktops applications to call Microsoft Graph in the name of a user. For details, see Acquiring tokens interactively.
var scopes = new[] { "User.Read" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Value from app registration
var clientId = "YOUR_CLIENT_ID";
// using Azure.Identity;
var options = new InteractiveBrowserCredentialOptions
{
TenantId = tenantId,
ClientId = clientId,
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
// MUST be http://localhost or http://localhost:PORT
// See https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/System-Browser-on-.Net-Core
RedirectUri = new Uri("http://localhost"),
};
// https://learn.microsoft.com/dotnet/api/azure.identity.interactivebrowsercredential
var interactiveCredential = new InteractiveBrowserCredential(options);
var graphClient = new GraphServiceClient(interactiveCredential, scopes);
Username/password provider
The username/password provider allows an application to sign in a user by using their username and password. Use this flow only when you cannot use any of the other OAuth flows. For more information, see Microsoft identity platform and the OAuth 2.0 resource owner password credential
var scopes = new[] { "User.Read" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Value from app registration
var clientId = "YOUR_CLIENT_ID";
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
var userName = "adelev@contoso.com";
var password = "P@ssword1!";
// https://learn.microsoft.com/dotnet/api/azure.identity.usernamepasswordcredential
var userNamePasswordCredential = new UsernamePasswordCredential(
userName, password, tenantId, clientId, options);
var graphClient = new GraphServiceClient(userNamePasswordCredential, scopes);
Next steps
- For code samples that show you how to use the Microsoft identity platform to secure different application types, see Microsoft identity platform code samples (v2.0 endpoint).
- Authentication providers require an client ID. You'll want to register your application after you set up your authentication provider.
- Let us know if a required OAuth flow isn't currently supported by voting for or opening a Microsoft Graph feature request.
Feedback
Submit and view feedback for