-
Notifications
You must be signed in to change notification settings - Fork 192
How Authentication Works in TeamsFx
Note: This documentation applies to TeamsFx SDK version >= 2.0.0.
A typical Teams tab application usually needs to obtain a currently logged-in user identity to build a single sign-on experience for the application user. To access user information protected by Microsoft Entra and to access data from services like Facebook and Twitter, the application needs to establish a trusted connection with those providers. For example, if your application is calling Microsoft Graph APIs to obtain a user's profile photo, you need to authenticate the user to retrieve the appropriate authentication tokens.
frontend only Teams Tab application created by Teams Toolkit, we leverage the Microsoft Entra Auth Code Flow as the authentication mechanism to provide user login experience in Teams Tab apps. The template provides a simple Teams Tab that can get user login information.
The sequence chart below shows how the authentication flow works in a frontend only Teams Tab application.
Latest TeamsFx SDK uses msal-browser for Auth Code Flow with PKCE authentication.
-
In the Teams Tab app, add the following code to trigger the login flow:
const authConfig: TeamsUserCredentialAuthConfig = { clientId: process.env.REACT_APP_CLIENT_ID!, initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL!, }; const teamsUserCredential = new TeamsUserCredential(authConfig); // Put the login code below in a call-to-action callback function to avoid browser blocking automatically showing up pop-ups. const scope = ["User.Read"]; await teamsUserCredential.login(scope);
Note: Due to the limitation of msal, multiple instances of
TeamsUserCredential
is not recommended. -
When
teamsUserCredential.login
function is triggered, TeamsFx SDK would pop up a window and navigate to auth-start.html undertabs/public
in your project. The above code would readREACT_APP_START_LOGIN_PAGE_URL
from env as the endpoint of auth-start.html. You can customize your endpoint by updatinginitiateLoginEndpoint
ofauthConfig
. -
In auth-start.html, will navigate to Microsoft Entra login page using msal. You can find the template of auth-start.html here for JavaScript and here for TypeScript.
-
After login in the Microsoft Entra login page, user will be redirected to auth-end.html. In auth-end.html, will use msal to use Auth Code Flow with PKCE. Since msal use the session storage for cache, will return session storage to SDK. The scheme of response will be:
{ "sessionStorage": { "key": "value", ... }, ... }
You can find the template of auth-end.html here for JavaScript and here for TypeScript.
-
TeamsFx SDK will get the response from the auth-end page, and will:
- If the response is empty or can not parse to JSON object, will return error.
- If "code" exists in the response, will return error. You can check here for detail.
- If "sessionStorage" exists in the response, will set the key value pairs to the session storage.
-
After this, the login flow has been completed. You can use the following code to call Graph API:
const graphClient = createMicrosoftGraphClientWithCredential(teamsUserCredential, ["User.Read"]); const profile = await graphClient.api("/me").get();
When getting token flow is triggered, Teams SDK will first try to use msal to check whether Access Token exists in session storage. Here msal will handle the scenario that the token exists and is expired. If succeeded, return Access Token. If failed to get Access Token from session storage, Teams SDK will try to use msal to launch silent SSO. If succeeded, return Access Token. If failed in silent SSO, you need to trigger the login flow to get Access Token.
If your Teams Tab App has an backend service such as Azure Function application, and you want to access current user information protected by Microsoft Entra in backend service, for example, if your Azure Function needs to call Microsoft Graph APIs to obtain a user's profile photo, then you need to authenticate the user with On-Behalf-Of flow to retrieve the appropriate authentication tokens.
The sequence chart below shows how the On-Behalf-Of flow works in a Teams Tab app.
Step 1: Teams Tab App sends request with SSO token in header to Azure Function backend
Step 2,3: Azure Function calls Microsoft Entra use OBO flow to exchange access token for Graph API
Step 4,5: Azure Function use access token to call Graph API
Step 6: Azure Function send back result to Teams Tab
Latest TeamsFx SDK uses msal-node for On-Behalf-Of flow authentication.
-
To call Azure Function to get user information, the Teams Tab client sends an HTTP request with an SSO token in the
Authorization
header. The token can be retrieved using the TeamsFx SDK from your app's client (custom tab). Below is an example:const authConfig: TeamsUserCredentialAuthConfig = { clientId: process.env.REACT_APP_CLIENT_ID!, initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL!, }; const teamsUserCredential = new TeamsUserCredential(authConfig); const accessToken = await teamsUserCredential.getToken(""); // note: empty string argument on the previous line is required for now, this will be fixed in a later release const response = await fetch(`${functionEndpoint}/api/${functionName}`, { headers: { Authorization: `Bearer ${accessToken.token}`, }, });
-
In the Azure Function app, use
OnBehalfOfUserCredential
to call Graph API for current user usingssoToken
retrieved from request header as below:const authConfig: OnBehalfOfCredentialAuthConfig = { authorityHost: config.authorityHost, tenantId: config.tenantId, clientId: config.clientId, clientSecret: config.clientSecret, }; let credential = new OnBehalfOfUserCredential(ssoToken, authConfig); const graphClient: Client = createMicrosoftGraphClientWithCredential(credential, [".default"]); const profile: any = await graphClient.api("/me").get();
Note:
ssoToken
is retrieved from request header -
When Graph API is called, if user doesn't consent before, it will throw error. Then Teams Tab app needs to show login button and ask user to consent the permission as below:
const authConfig: TeamsUserCredentialAuthConfig = { clientId: process.env.REACT_APP_CLIENT_ID!, initiateLoginEndpoint: process.env.REACT_APP_START_LOGIN_PAGE_URL!, }; const teamsUserCredential = new TeamsUserCredential(authConfig); // Put the login code below in a call-to-action callback function to avoid browser blocking automatically showing up pop-ups. const scope = ["User.Read"]; await teamsUserCredential.login(scope);
In the client credentials flow, permissions are granted directly to the application itself by an administrator. When the app presents a token to a resource, the resource enforces that the app itself has authorization to perform an action since there is no user involved in the authentication.
The entire client credentials flow looks similar to the following diagram as below:
Latest TeamsFx SDK uses msal-node for On-Behalf-Of flow authentication.
-
Grant application permission in the Microsoft Entra application follow this link.
-
After permissions are granted, then in the Azure Function, use
AppCredential
in TeamsFx SDK to call Graph API as below:const appAuthConfig: AppCredentialAuthConfig = { authorityHost: process.env.M365_AUTHORITY_HOST, clientId: process.env.M365_CLIENT_ID, tenantId: process.env.M365_TENANT_ID, clientSecret: process.env.M365_CLIENT_SECRET, }; const appCredential = new AppCredential(appAuthConfig); const graphClient: Client = createMicrosoftGraphClientWithCredential(appCredential, [".default"]); const profile: any = await graphClient.api("/users/" + userName).get();
-
This sample demonstrate auth flows using TeamsFx SDK: Hello World Tab with Backend Sample
Build Custom Engine Copilots
- Build a basic AI chatbot for Teams
- Build an AI agent chatbot for Teams
- Expand AI bot's knowledge with your content
Scenario-based Tutorials
- Send notifications to Teams
- Respond to chat commands in Teams
- Respond to card actions in Teams
- Embed a dashboard canvas in Teams
Extend your app across Microsoft 365
- Teams tabs in Microsoft 365 and Outlook
- Teams message extension for Outlook
- Add Outlook Add-in to a Teams app
App settings and Microsoft Entra Apps
- Manage Application settings with Teams Toolkit
- Manage Microsoft Entra Application Registration with Teams Toolkit
- Use an existing Microsoft Entra app
- Use a multi-tenant Microsoft Entra app
Configure multiple capabilities
- How to configure Tab capability within your Teams app
- How to configure Bot capability within your Teams app
- How to configure Message Extension capability within your Teams app
Add Authentication to your app
- How to add single sign on in Teams Toolkit for Visual Studio Code
- How to enable Single Sign-on in Teams Toolkit for Visual Studio
Connect to cloud resources
- How to integrate Azure Functions with your Teams app
- How to integrate Azure API Management
- Integrate with Azure SQL Database
- Integrate with Azure Key Vault
Deploy apps to production