Authentication overview
Microsoft Graph API serves as a unified endpoint to access data and intelligence from Microsoft 365, Windows, and Enterprise Mobility + Security. To ensure secure interaction with this data, Microsoft Graph API employs robust authentication mechanisms, primarily built upon the OAuth 2.0 authorization framework and Microsoft Entra ID (formerly Azure Active Directory) as its identity provider. All requests to Microsoft Graph API must include an access token, which grants the client application specific permissions to perform operations on behalf of a user or itself.
The authentication process typically involves an application acquiring an access token from Microsoft Entra ID, then presenting this token in the Authorization header of HTTP requests to Microsoft Graph API. The token contains claims that verify the application's identity and the permissions it has been granted. Microsoft Graph API then validates this token, ensuring its authenticity, expiry, and the scope of permissions, before processing the request.
Developers must register their applications with Microsoft Entra ID to obtain the necessary credentials and configure required permissions. Permissions in Microsoft Graph API are granular, allowing applications to request access only to the specific resources and operations they need, adhering to the principle of least privilege. These permissions can be either delegated (on behalf of a user) or application permissions (without a signed-in user).
Supported authentication methods
Microsoft Graph API supports several OAuth 2.0 flows to accommodate different application scenarios. The choice of flow depends on the application type, its interaction with users, and whether it operates client-side or server-side.
| Method (OAuth 2.0 Flow) | When to Use | Security Level |
|---|---|---|
| Authorization Code Flow | Web applications, mobile and desktop applications requiring user interaction. | High: Relies on server-side token exchange, keeping client secret secure. |
| Client Credentials Flow | Daemon applications, services, or scripts that operate without a signed-in user (e.g., background services, automated tasks). | High: Requires application secret/certificate, no user context. |
| On-Behalf-Of (OBO) Flow | Mid-tier services or APIs that need to call Microsoft Graph API on behalf of a user who has already authenticated to the mid-tier service. | High: Propagates user identity and permissions through a chain of services. |
| Implicit Grant Flow (deprecated) | Single-page applications (SPAs). While still supported for backward compatibility, Microsoft recommends Authorization Code Flow with PKCE for SPAs. | Moderate: Tokens exposed in browser history/URL; no refresh tokens. |
| Resource Owner Password Credentials (ROPC) Flow (limited use) | Highly trusted applications where the user's username and password can be securely handled. Generally discouraged due to security concerns. | Low: Exposes user credentials to the client application. Avoid if possible. |
Each flow dictates how an application obtains an access token from Microsoft Entra ID. For interactive applications, the Authorization Code Flow is generally recommended, often combined with Proof Key for Code Exchange (PKCE) for enhanced security in public clients like mobile and single-page applications.
Getting your credentials
To authenticate with Microsoft Graph API, applications must first be registered within Microsoft Entra ID. This process provides the necessary application credentials and allows for the configuration of API permissions.
-
Register your application: Navigate to the Azure portal and search for "App registrations". Select "New registration" and provide a name for your application. Choose the supported account types (e.g., "Accounts in this organizational directory only" or "Accounts in any organizational directory and personal Microsoft accounts"). Configure the Redirect URI based on your application type (e.g.,
http://localhostfor development, a specific URL for web apps, or a custom scheme for mobile apps). For detailed instructions, refer to the Microsoft Graph API app registration documentation. - Record Application (client) ID: After registration, you will receive an Application (client) ID. This unique identifier is used by the authentication library (MSAL) to identify your application to Microsoft Entra ID.
-
Generate a client secret or upload a certificate:
- Client Secret: For confidential client applications (e.g., web apps, daemon services), you typically generate a client secret. Under the "Certificates & secrets" section of your app registration, create a new client secret. Make sure to record the secret value immediately, as it will only be shown once. This secret is used by your application to authenticate itself to Microsoft Entra ID.
- X.509 Certificate: For higher security and production environments, using an X.509 certificate for client authentication is recommended over client secrets. Upload the public key of your certificate in the "Certificates & secrets" section. Your application will then use the private key to sign authentication requests.
-
Configure API permissions: Under the "API permissions" section, add the necessary Microsoft Graph API permissions. Permissions are categorized as "Delegated permissions" (for user interaction) or "Application permissions" (for daemon apps). Select the specific permissions required by your application (e.g.,
User.Read,Mail.Send,Files.ReadWrite.All). For application permissions, an administrator must grant "admin consent" before your application can use them.
Authenticated request example
This example demonstrates how to obtain an access token using the Client Credentials flow (suitable for daemon applications) and then use it to make a request to Microsoft Graph API. We'll use a hypothetical Python example with the requests library for clarity, assuming you have your TENANT_ID, CLIENT_ID, and CLIENT_SECRET.
import requests
import json
# Your application credentials
TENANT_ID = "YOUR_TENANT_ID" # Directory (tenant) ID
CLIENT_ID = "YOUR_CLIENT_ID" # Application (client) ID
CLIENT_SECRET = "YOUR_CLIENT_SECRET" # Client secret value
# Microsoft Entra ID token endpoint
TOKEN_URL = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token"
# Microsoft Graph API endpoint
GRAPH_API_URL = "https://graph.microsoft.com/v1.0/users"
# 1. Obtain an access token using Client Credentials Flow
token_data = {
"client_id": CLIENT_ID,
"scope": "https://graph.microsoft.com/.default", # Request all permissions configured for the app
"client_secret": CLIENT_SECRET,
"grant_type": "client_credentials"
}
token_r = requests.post(TOKEN_URL, data=token_data)
token_r.raise_for_status() # Raise an exception for HTTP errors
token_response = token_r.json()
access_token = token_response.get("access_token")
if not access_token:
print("Failed to obtain access token.")
exit()
print("Access token obtained successfully.")
# 2. Make an authenticated request to Microsoft Graph API
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
graph_r = requests.get(GRAPH_API_URL, headers=headers)
graph_r.raise_for_status() # Raise an exception for HTTP errors
users_data = graph_r.json()
print(json.dumps(users_data, indent=2))
# Example of retrieving a specific user
# user_id = users_data["value"][0]["id"] # Assuming there's at least one user
# specific_user_url = f"{GRAPH_API_URL}/{user_id}"
# specific_user_r = requests.get(specific_user_url, headers=headers)
# specific_user_r.raise_for_status()
# print("\nSpecific user data:")
# print(json.dumps(specific_user_r.json(), indent=2))
This script first sends a POST request to Microsoft Entra ID's token endpoint to exchange application credentials for an access token. Upon successful acquisition, it then uses this access_token in the Authorization header of a GET request to the Microsoft Graph API /users endpoint to retrieve a list of users in the directory, demonstrating the typical flow for application-level access.
Security best practices
Implementing strong security measures is crucial when authenticating with Microsoft Graph API, especially since it involves access to sensitive organizational and user data.
- Principle of Least Privilege: Always request the minimum set of permissions necessary for your application to function. Over-privileged applications increase the attack surface and potential impact of a security breach. Review and update permissions regularly.
-
Secure Client Secrets/Certificates:
- Client Secrets: Treat client secrets as highly sensitive information. Never embed them directly in client-side code, commit them to version control, or expose them in public repositories. Store them in secure environment variables, Azure Key Vault, or other secure secret management systems. Rotate client secrets regularly, typically annually or semi-annually.
- Certificates: For production environments, use X.509 certificates instead of client secrets. Certificates offer stronger security as the private key is not transmitted over the network and can be stored more securely. Ensure the private key is properly protected and never exposed.
-
Validate Redirect URIs: When registering your application, specify exact and secure Redirect URIs. Avoid using wildcard Redirect URIs (e.g.,
*). This prevents token leakage to unauthorized endpoints. - Use Microsoft Authentication Library (MSAL): Microsoft provides official Microsoft Authentication Library (MSAL) for various platforms and languages. MSAL simplifies the authentication process, handles token caching, refresh token management, and adheres to security best practices, reducing the likelihood of common implementation errors.
- Error Handling and Logging: Implement robust error handling for authentication failures. Log authentication attempts and failures for monitoring and auditing purposes, but ensure sensitive information (like tokens or credentials) is not logged.
- Token Validation: While MSAL handles much of the token validation, if you are manually handling tokens, always validate the access token received from Microsoft Entra ID. This includes checking the issuer, audience, expiry, and signature to ensure it's legitimate and intended for your application.
- Secure Token Storage: Access tokens and refresh tokens should be stored securely. For web applications, use HTTP-only, secure cookies. For desktop/mobile applications, use platform-specific secure storage mechanisms (e.g., iOS Keychain, Android Keystore, Windows Credential Manager).
- Regular Security Audits: Periodically review your application's authentication implementation, registered permissions, and secret management practices to identify and mitigate potential vulnerabilities.