MS-900Chapter 93 of 104Objective 3.3

Securing Microsoft 365 Apps: OAuth and App Consent

This chapter covers OAuth 2.0 and app consent in Microsoft 365, a critical security topic for the MS-900 exam. Understanding how Microsoft 365 uses OAuth to authorize third-party apps and how admins manage consent is essential, as approximately 10-15% of exam questions touch on app permissions, consent, and security. We will explore the OAuth flow in detail, the different types of permissions, admin consent, user consent, and how to audit and control app access.

25 min read
Intermediate
Updated May 31, 2026

OAuth 2.0 as a Hotel Key System

Imagine a hotel where guests need access to various rooms and facilities. The hotel has a front desk (the authorization server). A guest checks in and receives a key card (the access token) that grants access only to their assigned room and, say, the gym and pool, but not the staff offices or other guests' rooms. The key card has an expiration time printed on it, and it cannot be used after checkout. If the guest wants to access a restricted area like the business center, they must return to the front desk with proof of identity (a passport) and request a new key card with that additional permission. The front desk verifies their identity and issues a new key card with the updated scope. The hotel staff (resource servers) do not need to check the guest's identity each time; they simply scan the key card and check that it has the correct permissions and is not expired. This is exactly how OAuth 2.0 works: a client application (guest) obtains an access token (key card) from an authorization server (front desk) after the user (hotel guest) consents. The token is then presented to the resource server (hotel door) to access protected resources. The token contains scopes (permissions) and an expiration time. If the client needs additional permissions, it must go through a new consent flow.

How It Actually Works

What is OAuth 2.0 and Why Does Microsoft 365 Use It?

OAuth 2.0 (RFC 6749) is an open standard for token-based authorization. It allows third-party applications to access user data hosted on a resource server without exposing the user's credentials. In Microsoft 365, OAuth 2.0 is the foundation for all delegated access to Microsoft Graph, SharePoint, Exchange Online, and other services. Instead of sharing a password, the user authenticates once, and the app receives a limited-scope, time-limited token.

How OAuth 2.0 Works in Microsoft 365

The OAuth 2.0 flow involves four parties: - Resource Owner: The user who owns the data (e.g., a Microsoft 365 user). - Client: The application requesting access (e.g., a third-party app like a CRM tool). - Authorization Server: The Microsoft identity platform (Azure AD) that issues tokens after authentication and consent. - Resource Server: The API that hosts the data (e.g., Microsoft Graph).

The most common flow for delegated access is the Authorization Code Grant Flow (OAuth 2.0 authorization code grant). Step-by-step: 1. The client app redirects the user to the Azure AD authorize endpoint (https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize). 2. The user authenticates (if not already) and sees a consent prompt listing the permissions the app requests. 3. If the user consents, Azure AD sends an authorization code back to the client via a redirect URI. 4. The client exchanges that code for an access token (and optionally a refresh token) by calling the token endpoint (https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token). 5. The client uses the access token in the Authorization: Bearer header to call Microsoft Graph APIs.

Key Components: Permissions, Scopes, and Consent

Permissions are divided into two types: - Delegated permissions: The app acts on behalf of a signed-in user. The app can only do what the user is allowed to do. Example: Mail.Read allows reading the signed-in user's mail. - Application permissions: The app runs as a background service without a signed-in user. These require admin consent and are powerful (e.g., Mail.Read.All allows reading any user's mail in the organization).

Scopes are the specific permissions requested. For Microsoft Graph, scopes are strings like User.Read, Mail.Send, Files.ReadWrite.All. The client requests scopes in the authorization request.

Consent is the act of granting permission. There are two types: - User consent: The user consents to delegated permissions on their own behalf. By default, users can consent to low-impact permissions (e.g., User.Read, openid, profile, email). Admins can control which permissions users are allowed to consent to via User consent settings in Azure AD. - Admin consent: An administrator consents on behalf of the entire organization. Required for application permissions or high-risk delegated permissions (e.g., Mail.ReadWrite.All). Admin consent cannot be undone by individual users; only an admin can revoke it.

Default Values and Timers

Access token lifetime: By default, Microsoft identity platform access tokens are valid for 60-90 minutes (configurable via token lifetime policies). The actual value depends on the resource; Microsoft Graph tokens default to 60 minutes.

Refresh token lifetime: Refresh tokens are valid for 90 days by default. If the user does not use the app for 90 days, the refresh token expires and the user must re-authenticate. This can be configured up to a maximum of 365 days or set to never expire (not recommended).

ID token lifetime: ID tokens (OpenID Connect) are valid for 1 hour by default.

Configuration and Verification

Admins manage app permissions and consent in the Azure AD admin center under Enterprise applications > App registrations > select an app > API permissions. Here, you can add permissions and grant admin consent.

To audit consent grants, use the Microsoft Entra admin center > Identity > Applications > Enterprise applications > Consent and permissions > User consent settings and Admin consent settings. You can review all consent requests and revoke them.

Using PowerShell, you can list all OAuth2 permission grants with the Microsoft Graph PowerShell SDK:

Connect-MgGraph -Scopes "Directory.Read.All"
Get-MgOauth2PermissionGrant -All

To revoke a specific grant:

Remove-MgOauth2PermissionGrant -OAuth2PermissionGrantId "<grant-id>"

Interaction with Conditional Access

OAuth tokens are subject to Conditional Access policies. When a user authenticates, Azure AD evaluates policies based on the user, device, location, and app. If a policy requires multi-factor authentication (MFA), the token will only be issued after MFA is completed. The token itself contains claims about the authentication context (e.g., acr claim indicating MFA). Resource servers can validate these claims.

App Consent Policies

Admins can configure Admin consent workflows to allow users to request admin consent for permissions they cannot consent to themselves. This is set in Azure AD > Enterprise applications > Consent and permissions > Admin consent settings. When enabled, users see a prompt to request approval, and designated reviewers can approve or deny.

Microsoft Graph permissions are categorized into three tiers: - Low: Basic profile, sign-in, openid, email, offline_access. Users can consent by default. - Medium: Permissions that read or write user data but with limited scope (e.g., Calendars.Read, Mail.Read). Admins can allow user consent for these. - High: Permissions with broad data access (e.g., Mail.ReadWrite.All, Directory.ReadWrite.All). These require admin consent.

Common Misconfiguration: Over-Permissioned Apps

A frequent security issue is granting excessive permissions to apps. For example, a simple note-taking app requesting Mail.ReadWrite.All (read and write all mail) instead of just Mail.Read. The principle of least privilege should be applied. Use the Permissions tab in Azure AD to review granted permissions and remove unnecessary ones.

Revoking Consent

Users can revoke consent for apps in the My Apps portal (https://myapps.microsoft.com) by selecting the app and clicking Remove. Admins can revoke consent for any app in the Azure AD portal under Enterprise applications > select app > Permissions > Revoke admin consent.

Summary of Exam-Relevant Points

OAuth 2.0 is used for delegated access; OpenID Connect is used for authentication (ID token).

Delegated permissions require a signed-in user; application permissions do not.

User consent is for low/medium delegated permissions; admin consent is required for high-risk delegated and all application permissions.

Default access token lifetime: 60-90 minutes (Microsoft Graph: 60 minutes).

Refresh token default: 90 days of inactivity.

Consent can be reviewed and revoked by users (self) and admins (all).

Conditional Access policies can enforce MFA and other controls at token issuance.

Walk-Through

1

User Initiates App Login

The user navigates to the third-party app and clicks 'Sign in with Microsoft'. The app constructs an authorization request URL with parameters: client_id (app's ID), response_type=code, redirect_uri (where to send the auth code), scope (e.g., 'User.Read Mail.Read'), and state (a random value for CSRF protection). The user's browser is redirected to the Microsoft identity platform authorize endpoint.

2

User Authenticates

The user enters their credentials on the Microsoft login page. If multi-factor authentication is required by Conditional Access, the user completes that step. Upon successful authentication, the authorization server creates an authentication session. The user is then presented with a consent screen listing the requested permissions (scopes).

3

User Consents

The user reviews the permissions and clicks 'Accept'. This consent is recorded as an OAuth2PermissionGrant object in Azure AD. The authorization server generates an authorization code (short-lived, typically 10 minutes) and sends it to the redirect_uri as a query parameter. The code is single-use.

4

App Exchanges Code for Token

The app receives the authorization code and sends a POST request to the token endpoint with the code, client_id, client_secret (or certificate), redirect_uri, and grant_type=authorization_code. The authorization server validates the code and client credentials, then returns an access token (JWT), an ID token (if openid scope was requested), and a refresh token (if offline_access scope was requested). The access token contains claims such as aud (audience), iss (issuer), iat (issued at), exp (expiration), scp (scopes), and oid (object ID of the user).

5

App Calls Microsoft Graph

The app uses the access token to call Microsoft Graph APIs. It adds an HTTP header: 'Authorization: Bearer <access_token>'. Microsoft Graph validates the token signature, checks expiration, and verifies that the token's scopes include the required permissions. If valid, the API returns the requested data. If the token is expired, the app uses the refresh token to obtain a new access token without user interaction.

What This Looks Like on the Job

Scenario 1: Third-Party CRM Integration

A company uses a CRM application that needs to read users' calendars and send emails on their behalf. The admin registers the CRM app in Azure AD and requests delegated permissions Calendars.Read and Mail.Send. The admin grants admin consent so that all users in the organization can use the app without seeing a consent prompt. The app uses the OAuth authorization code flow. In production, the app handles token refresh automatically. A common issue is that the app's redirect URI is misconfigured (e.g., using HTTP instead of HTTPS), causing the authorization code to be intercepted. The admin must ensure the redirect URI is exactly as registered.

Scenario 2: Background Service for Mail Archiving

An organization deploys a mail archiving service that runs as a daemon and needs to read all users' mail. This requires application permission Mail.Read.All. The admin registers the app and grants admin consent for that permission. The app uses the client credentials grant flow, where it authenticates with its client ID and client secret (or certificate) to obtain an access token directly, without any user. The token is valid for 60 minutes. The service must handle token expiration by requesting a new token. A misconfiguration here is using a delegated permission instead of application permission, causing the service to fail when no user is signed in.

Scenario 3: User-Consented App Gone Rogue

An employee installs a free productivity app that requests Files.ReadWrite.All and Mail.ReadWrite. The user consents, not realizing the app can read and write all their files and emails. Later, the app exfiltrates data. The admin discovers the issue via the Azure AD audit logs (sign-in logs and consent events). The admin revokes the app's permissions globally. To prevent this, the admin should configure user consent settings to block high-risk permissions and enable the admin consent workflow. The admin also implements Conditional Access policies that require compliant devices for app access.

Performance and Scale

OAuth token issuance is handled by Azure AD, which is highly scalable. For large organizations with thousands of apps, the main challenge is managing consent and auditing. Azure AD can handle millions of token requests per day. The token size is typically 2-4 KB. The refresh token rotation (new refresh token issued with each refresh) is supported to improve security.

How MS-900 Actually Tests This

What MS-900 Tests

The MS-900 exam objective 3.3 covers 'Describe the security capabilities of Microsoft 365' and specifically includes app permissions and consent. Expect 3-5 questions on:

Distinguishing between delegated and application permissions.

Understanding when admin consent is required.

Knowing the default token lifetimes (access token 60-90 min, refresh token 90 days).

Recognizing the consent prompt and how users can review/revoke consent.

Identifying the correct flow for different scenarios (delegated vs. app-only).

Common Wrong Answers and Why

1.

'Application permissions require user consent.' This is false. Application permissions are granted only by admin consent; there is no user involved.

2.

'Access tokens are valid for 24 hours.' Wrong. The default is 60-90 minutes, not 24 hours. This is a trap because other systems may have longer lifetimes.

3.

'Users can grant admin consent.' False. Only admins can grant admin consent. Users can only grant user consent for delegated permissions.

4.

'Refresh tokens never expire.' Wrong. Default is 90 days of inactivity, configurable but not infinite.

Specific Numbers and Terms on the Exam

Delegated permission: User.Read (low), Mail.Read (medium), Mail.ReadWrite.All (high).

Application permission: Mail.Read.All, Directory.ReadWrite.All.

Token endpoint: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token.

Admin consent endpoint: https://login.microsoftonline.com/{tenant}/v2.0/adminconsent.

Default access token lifetime: 60 minutes for Microsoft Graph.

Default refresh token inactivity timeout: 90 days.

Edge Cases

Multi-tenant apps: An app registered in one tenant can request access to another tenant's data. The user in the target tenant must consent, or an admin must grant admin consent for the entire tenant.

Consent for personal Microsoft accounts: For Microsoft accounts (e.g., Outlook.com), consent is always user consent; there is no admin.

Incremental consent: Apps can request additional permissions dynamically (dynamic consent) by including new scopes in the authorization request. This prompts the user again.

How to Eliminate Wrong Answers

If the scenario describes an app running without a user (e.g., a service, daemon), the answer must involve application permissions and admin consent, not user consent.

If the question mentions 'on behalf of a user', it's delegated permissions.

If the question asks about the maximum time a token is valid, remember the default is 60 minutes (or 90 min for some resources), not hours or days.

For consent revocation, know that users can revoke in My Apps, admins in Azure AD.

Key Takeaways

OAuth 2.0 is for authorization; OpenID Connect is for authentication.

Delegated permissions require a user; application permissions do not.

Admin consent is mandatory for application permissions and high-risk delegated permissions.

Default access token lifetime for Microsoft Graph is 60 minutes.

Default refresh token inactivity timeout is 90 days.

Users can revoke consent via My Apps; admins can revoke via Azure AD.

Conditional Access policies are evaluated at token issuance, not at API call.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Delegated Permissions

Requires a signed-in user.

App acts on behalf of the user.

User or admin can consent (depending on risk level).

Scopes are user-specific (e.g., Mail.Read).

Common for interactive apps.

Application Permissions

No signed-in user required.

App runs as a background service.

Only admin can consent.

Scopes are tenant-wide (e.g., Mail.Read.All).

Common for daemons and services.

Watch Out for These

Mistake

OAuth 2.0 is used for authentication.

Correct

OAuth 2.0 is for authorization only. OpenID Connect (OIDC) is the authentication layer built on top of OAuth 2.0. OAuth 2.0 provides access tokens; OIDC provides ID tokens for authentication.

Mistake

Application permissions can be granted by users.

Correct

Application permissions always require admin consent. Users cannot grant application permissions because they operate without a signed-in user and have broad access.

Mistake

Access tokens are valid indefinitely.

Correct

Access tokens have a limited lifetime, typically 60-90 minutes. They must be refreshed using a refresh token. Refresh tokens have a default inactivity timeout of 90 days.

Mistake

Once a user consents, the app can access data forever.

Correct

Consent can be revoked by the user or an admin. Also, refresh tokens expire after 90 days of inactivity, requiring the user to re-consent if the app is not used.

Mistake

All apps in Microsoft 365 use OAuth 2.0.

Correct

Legacy protocols like Basic authentication and Active Directory Authentication Library (ADAL) are deprecated. However, some older apps may still use them. Microsoft recommends OAuth 2.0 with Microsoft Authentication Library (MSAL).

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

What is the difference between delegated and application permissions in Microsoft 365?

Delegated permissions allow an app to act on behalf of a signed-in user, with access limited to what the user can do. Application permissions allow an app to access data without a signed-in user, typically with broader, tenant-wide access. Delegated permissions can be consented to by users (for low-risk) or admins; application permissions always require admin consent.

How long is an OAuth access token valid in Microsoft 365?

By default, access tokens issued by the Microsoft identity platform are valid for 60-90 minutes. For Microsoft Graph, the default is 60 minutes. This can be changed using token lifetime policies, but the default is what MS-900 tests.

Can a user consent to an app that requests 'Mail.ReadWrite.All'?

No, by default users cannot consent to high-risk permissions like 'Mail.ReadWrite.All'. This permission requires admin consent. Admins can configure user consent settings to allow or block specific permissions, but the default blocks high-risk permissions.

How do I revoke consent for an app in Microsoft 365?

Users can revoke consent by going to the My Apps portal (https://myapps.microsoft.com), selecting the app, and clicking 'Remove'. Admins can revoke consent for any app in the Azure AD admin center under Enterprise applications > select app > Permissions > Revoke admin consent. Admins can also revoke all consents for a user via PowerShell.

What is the purpose of the refresh token in OAuth 2.0?

The refresh token allows an app to obtain a new access token without requiring the user to re-authenticate. It is issued along with the access token when the 'offline_access' scope is requested. The refresh token has a longer lifetime (default 90 days inactivity) and can be used to get new access tokens after the current one expires.

What happens if a user denies consent during the OAuth flow?

If the user denies consent, the authorization server does not issue an authorization code. The user is redirected back to the app with an error parameter (e.g., 'error=access_denied'). The app must handle this error gracefully, typically by showing a message that consent is required.

Can an app request additional permissions after initial consent?

Yes, this is called incremental consent. The app can initiate a new authorization request with additional scopes. The user (or admin) must consent to the new permissions. This is useful for apps that need to expand functionality over time.

Terms Worth Knowing

Ready to put this to the test?

You've just covered Securing Microsoft 365 Apps: OAuth and App Consent — now see how well it sticks with free MS-900 practice questions. Full explanations included, no account needed.

Done with this chapter?