100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Microsoft 365

Single Sign-On (SSO) in Teams Apps

Understand how Teams apps silently authenticate users through Microsoft Entra ID using the getAuthToken and On-Behalf-Of flows.

IntegrationIntermediate9 min readJul 10, 2026
Analogies

Why SSO Matters in Teams Apps

A Teams app runs inside an iframe or webview hosted by the Teams client, and without SSO the user would have to complete a separate sign-in popup the first time they open any tab, bot, or personal app. Teams SSO lets the app silently obtain an identity token for the already-signed-in Teams user through the Teams JavaScript SDK's authentication.getAuthToken (v1) or app.authentication.getAuthToken (v2) call, avoiding an extra consent screen for basic profile access and making the app feel native rather than bolted on.

🏏

Cricket analogy: This is like a player who's already been through ground-entry security for the stadium not needing to show ID again to walk from the dressing room to the nets — Teams SSO reuses the same trusted session instead of re-checking credentials at every door.

The getAuthToken Flow and On-Behalf-Of Exchange

When a tab calls app.authentication.getAuthToken(), the Teams client returns a short-lived Entra ID token scoped to the app's own Azure AD app registration — this token proves who the user is but typically cannot call Graph directly. The app's backend exchanges this token for a Graph-scoped access token using the OAuth 2.0 On-Behalf-Of (OBO) flow: it sends the original token, its client ID, and client secret to Entra ID's token endpoint and receives back a new token with the permissions the backend actually needs, such as Mail.Read or Chat.ReadWrite.

🏏

Cricket analogy: This is like a fielder passing the ball to the wicketkeeper who then relays it to the bowler for the run-out appeal — the initial token is the first throw, and the OBO exchange is the relay that gets it into the form actually needed.

javascript
// Frontend: request an SSO token inside the Teams tab
import { app, authentication } from "@microsoft/teams-js";

await app.initialize();
const clientToken = await authentication.getAuthToken();

// Send it to your backend for the OBO exchange
const res = await fetch("/api/graph/profile", {
  headers: { Authorization: `Bearer ${clientToken}` }
});

// Backend (Node.js, using msal-node ConfidentialClientApplication)
const oboRequest = {
  oboAssertion: clientToken,
  scopes: ["https://graph.microsoft.com/User.Read"]
};
const oboResponse = await cca.acquireTokenOnBehalfOf(oboRequest);
// oboResponse.accessToken can now call Graph directly

Configuring the App Registration and Manifest

SSO requires the Teams app manifest to declare a webApplicationInfo block containing the Entra ID application (client) ID and a resource URI matching api://{fully-qualified-domain}/{client-id}. The Entra ID app registration must expose an API with that same identifier URI, define a scope such as access_as_user, and pre-authorize the Teams client's own well-known application IDs so users aren't prompted with an unexpected consent screen the first time SSO fires.

🏏

Cricket analogy: This is like a ground's accreditation office pre-registering the broadcaster's specific camera crew IDs so they walk through the media gate without a manual check every match day — the manifest's webApplicationInfo is that pre-registration.

The identifier URI in your Entra ID app registration must exactly match the resource field in the manifest's webApplicationInfo, including the api:// scheme and domain — a mismatch is the single most common cause of SSO silently failing in production.

getAuthToken can fail with error 'resourceRequiresConsent' or similar when a user hasn't yet granted consent, especially the very first time or after scope changes. Always have a fallback path that opens a standard OAuth popup via authentication.authenticate() so the app degrades gracefully instead of breaking.

  • Teams SSO uses app.authentication.getAuthToken() to silently obtain a client-scoped Entra ID token for the signed-in user.
  • The On-Behalf-Of (OAuth 2.0) flow exchanges that client token for a Graph-scoped access token on the backend.
  • The app manifest's webApplicationInfo block must declare the Entra ID client ID and a matching api:// resource URI.
  • The Entra ID app registration exposes an API scope (commonly access_as_user) and pre-authorizes Teams' known client IDs.
  • A mismatched identifier URI between the manifest and app registration is a top cause of SSO failures.
  • Always implement a fallback OAuth popup for cases where silent SSO fails or consent hasn't been granted.
  • SSO removes the friction of a separate login popup, making Teams apps feel native rather than bolted on.

Practice what you learned

Was this page helpful?

Topics covered

#Microsoft365#MicrosoftTeamsDevelopmentStudyNotes#MicrosoftTechnologies#SingleSignOnSSOInTeamsApps#Single#Sign#SSO#Teams#StudyNotes#SkillVeris