Authentication overview

Microsoft Graph acts as a unified API endpoint for accessing data and intelligence from Microsoft 365, Windows 365, and other Microsoft cloud services. Secure access to this data requires robust authentication and authorization. Microsoft Graph relies on Azure Active Directory (Azure AD), Microsoft's cloud-based identity and access management service, as its security token service (STS). All applications integrating with Microsoft Graph must authenticate with Azure AD to obtain access tokens.

The authentication process typically involves an application requesting an access token from Azure AD, which then grants the token after successful authentication and authorization. This access token is a JSON Web Token (JWT) that contains claims about the authenticated principal (user or application) and the permissions granted. The application then includes this access token in the Authorization header of its HTTP requests to Microsoft Graph, typically in the format Bearer <access_token>.

Authorization for Microsoft Graph resources is managed through a granular permissions model. Applications must request specific permissions (scopes) for the data they intend to access. These permissions can be either delegated permissions, where the application acts on behalf of a signed-in user, or application permissions, where the application acts as its own identity without a user present. Administrators or users must consent to these permissions, depending on the scope and type of permission requested.

Supported authentication methods

Microsoft Graph supports various authentication flows based on the OAuth 2.0 authorization framework. The choice of flow depends on the application type and its requirements for user interaction and data access. The primary methods include:

Method When to Use Security Level
Authorization Code Flow Web applications, single-page applications (SPAs), mobile and desktop applications where a user signs in. High. Involves browser redirects, client secret (for web apps) or PKCE (for SPAs/mobile/desktop), and short-lived access tokens.
Client Credentials Flow Daemon applications, services, or background processes that need to access Microsoft Graph without a signed-in user. High. Relies on application's client secret or certificate for authentication. Requires application permissions.
On-Behalf-Of (OBO) Flow Middle-tier services that need to call Microsoft Graph on behalf of a user after receiving an access token from another service. High. Extends an existing delegated identity, propagating user context securely.
Device Code Flow Applications running on devices with limited input capabilities (e.g., smart TVs, IoT devices) where a user signs in on another device. Medium-High. User completes sign-in on a separate browser, reducing direct credential entry on the device.

Each flow is designed for specific scenarios to balance security, user experience, and application requirements. For example, the OAuth 2.0 Authorization Code Flow is standard for most web applications, providing a secure way to delegate user consent without exposing credentials directly to the client application.

Getting your credentials

To authenticate with Microsoft Graph, applications must first be registered with Azure AD. This registration process provides the necessary credentials and configuration for your application to interact with Azure AD and obtain tokens. The steps are:

  1. Register an application in Azure AD: Navigate to the Azure portal, go to Azure Active Directory, and select "App registrations." Choose "New registration" and provide a name for your application. Select the supported account types (e.g., accounts in this organizational directory only, or multi-tenant). For web applications, specify a redirect URI.
  2. Note Application (client) ID: After registration, Azure AD assigns a unique Application (client) ID to your application. This ID is essential for identifying your application during the authentication process.
  3. Generate a client secret or upload a certificate: For confidential client applications (e.g., web apps, daemon services), you'll need a client secret or a certificate. In the App registrations blade, under "Certificates & secrets," you can generate a new client secret. Store this secret securely, as it's only shown once. Alternatively, you can upload a public certificate, which is generally considered more secure for production environments.
  4. Configure API permissions: Under "API permissions," add the necessary Microsoft Graph permissions your application requires. For example, to read a user's calendar, you might add Calendars.Read. Choose between delegated permissions (for signed-in users) or application permissions (for daemon apps). Grant admin consent if required by the permissions chosen.
  5. Identify your tenant ID (optional but common): For applications operating within a specific Azure AD tenant, you'll also need the tenant ID, which can be found in the Azure AD overview. For multi-tenant applications, you might use the common endpoint instead of a specific tenant ID in your authentication requests.

These credentials (client ID, client secret/certificate, tenant ID) are then used by your application to request tokens from the Azure AD authentication endpoints. Microsoft provides Microsoft identity platform endpoints for different authentication scenarios.

Authenticated request example

Once you have obtained an access token using one of the supported OAuth 2.0 flows, you can include it in your HTTP requests to Microsoft Graph. The access token is placed in the Authorization header with the Bearer scheme.

Here's an example using curl to retrieve the signed-in user's profile information from the /me endpoint:

ACCESS_TOKEN="YOUR_ACCESS_TOKEN_HERE"

curl -X GET \
  "https://graph.microsoft.com/v1.0/me" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json"

In a typical application using one of the Microsoft Graph SDKs, the SDK handles the token acquisition and refresh process. For example, with the Microsoft Graph .NET SDK, you would configure an authentication provider:

using Azure.Identity;
using Microsoft.Graph;

// For a client credentials flow (daemon app)
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "YOUR_TENANT_ID";
var clientId = "YOUR_CLIENT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";

var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);

var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

// Now you can make requests
var user = await graphClient.Me.GetAsync();
Console.WriteLine($"Hello {user.DisplayName}");

This C# example demonstrates how to initialize a GraphServiceClient using the ClientSecretCredential from the Azure.Identity library, which then manages the token acquisition and attachment to requests automatically.

Security best practices

Securing your Microsoft Graph integrations is critical. Adhering to best practices helps protect sensitive data and maintain the integrity of your applications:

  • Least Privilege Principle: Request only the necessary permissions for your application to function. Avoid requesting overly broad permissions like User.ReadWrite.All if your application only needs to read a user's profile. This minimizes the impact of a potential compromise. Regularly review and audit assigned permissions.
  • Secure Credential Storage: Never hardcode client secrets directly in your application code. For web applications and services, use environment variables, Azure Key Vault, or other secure configuration management systems to store client secrets and certificates. Rotate client secrets regularly, typically every 90 days.
  • Use Certificates for Confidential Clients: For production confidential client applications, consider using X.509 certificates instead of client secrets. Certificates offer stronger cryptographic assurance and are generally harder to compromise than shared secrets. Manage certificate lifecycles carefully.
  • Validate Tokens and Scopes: If your application acts as a resource server (e.g., a middle-tier API calling Microsoft Graph), always validate incoming access tokens to ensure they are issued by Azure AD, are not expired, and contain the expected audience and scopes before making downstream calls to Microsoft Graph. The JWT.io debugger can help inspect token contents during development.
  • Implement Token Caching and Refresh: Access tokens are short-lived. Implement proper caching mechanisms for access tokens and use refresh tokens (where applicable, like in the Authorization Code Flow) to obtain new access tokens without requiring the user to re-authenticate. Ensure refresh tokens are also stored securely.
  • Error Handling and Logging: Implement robust error handling for authentication and authorization failures. Log relevant information (e.g., error codes, timestamps) for auditing and troubleshooting, but avoid logging sensitive data like access tokens or client secrets.
  • Regular Security Audits: Periodically review your application's Azure AD registration, including permissions, redirect URIs, and credential validity. Monitor Azure AD sign-in logs for suspicious activity related to your application.
  • Use Microsoft Authentication Libraries (MSAL): Leverage Microsoft's official Microsoft Authentication Libraries (MSAL) for various platforms and languages. MSAL simplifies the authentication process, handles token caching, refresh, and adherence to security best practices, reducing the chance of common implementation errors.