🔒 User Authentication
At times agents must access secured online resources on behalf of the user, such as checking email, checking on flight status, or placing an order. To enable this, the user must authenticate their identity and grant consent for the application to access these resources. This process results in the application receiving a token, which the application can then use to access the permitted resources on the user's behalf.
This is an advanced guide. It is highly recommended that you are familiar with Teams Core Concepts before attempting this guide.
User authentication does not work with the developer tools setup. You have to run the app in Teams. Follow Quickstart: Register your app to register and sideload your bot.
It is possible to authenticate the user into other auth providers like Facebook, Github, Google, Dropbox, and so on.
Once you have configured your Azure Bot resource OAuth settings, as described in the official documentation, add the following code to your App:
Project Setup​
Create an app with the graph template​
Skip this step if you want to add the auth configurations to an existing app.
The Teams Developer CLI doesn't ship a graph template for C# yet (tracked in microsoft/teams-sdk#2736). Scaffold the echo template and add the OAuth wiring shown below by hand:
teams project new csharp oauth-app
Set up the OAuth connection​
User authentication requires an Azure-managed bot (Teams-managed bots don't support OAuth connections). If you registered with --teams-managed, migrate first:
teams app bot migrate <appId> --subscription <id> --resource-group <your-resource-group>
Then follow the User Authentication Setup guide to configure the AAD app, create the Azure Bot OAuth connection, and update the manifest. The guide covers both SSO (silent token exchange) and generic OAuth.
If you'd rather have an AI coding assistant run the setup, install the teams-dev skill and ask it to "set up SSO for my Teams bot".
Configure the OAuth connection​
var builder = WebApplication.CreateBuilder(args);
var appBuilder = App.Builder()
.AddOAuth("graph");
builder.AddTeams(appBuilder);
var app = builder.Build();
var teams = app.UseTeams();
Make sure you use the same name you used when creating the OAuth connection in the Azure Bot Service resource.
In many templates, graph is the default name of the OAuth connection, but you can change that by supplying a different connection name in your app configuration.
Signing In​
This uses the Single Sign-On (SSO) authentication flow. To learn more about all the available flows and their differences see the official documentation.
You must call the signin method inside your route handler, for example: to signin when receiving the /signin message:
teams.OnMessage("/signin", async (context, cancellationToken) =>
{
if (context.IsSignedIn)
{
await context.Send("you are already signed in!", cancellationToken);
return;
}
else
{
await context.SignIn(cancellationToken);
}
});
Subscribe to the SignIn event​
You can subscribe to the signin event, that will be triggered once the OAuth flow completes.
teams.OnSignIn(async (_, teamsEvent, cancellationToken) =>
{
var context = teamsEvent.Context;
await context.Send($"Signed in using OAuth connection {context.ConnectionName}. Please type **/whoami** to see your profile or **/signout** to sign out.", cancellationToken);
});
Start using the graph client​
From this point, you can use the IsSignedIn flag and the userGraph client to query graph, for example to reply to the /whoami message, or in any other route.
The default OAuth configuration requests the User.ReadBasic.All permission. It is possible to request other permissions by modifying the App Registration for the bot on Azure.
teams.OnMessage("/whoami", async (context, cancellationToken) =>
{
if (!context.IsSignedIn)
{
await context.Send("you are not signed in!. Please type **/signin** to sign in", cancellationToken);
return;
}
var me = await context.GetUserGraphClient().Me.GetAsync();
await context.Send($"user \"{me!.DisplayName}\" signed in.", cancellationToken);
});
teams.OnMessage(async (context, cancellationToken) =>
{
if (context.IsSignedIn)
{
await context.Send($"You said : {context.Activity.Text}. Please type **/whoami** to see your profile or **/signout** to sign out.", cancellationToken);
}
else
{
await context.Send($"You said : {context.Activity.Text}. Please type **/signin** to sign in.", cancellationToken);
}
});
Signing Out​
You can signout by calling the signout method, this will remove the token from the User Token service cache
teams.OnMessage("/signout", async (context, cancellationToken) =>
{
if (!context.IsSignedIn)
{
await context.Send("you are not signed in!", cancellationToken);
return;
}
await context.SignOut(cancellationToken);
await context.Send("you have been signed out!", cancellationToken);
});
Handling Sign-In Failures​
When using SSO, if the token exchange fails Teams sends a signin/failure invoke activity to your app. The SDK includes a built-in default handler that logs a warning with actionable troubleshooting guidance. You can optionally register your own handler to customize the behavior:
teams.OnSignInFailure(async (context, cancellationToken) =>
{
var failure = context.Activity.Value;
Console.WriteLine($"Sign-in failed: {failure?.Code} - {failure?.Message}");
await context.Send("Sign-in failed.", cancellationToken);
});
The most common failure codes are installedappnotfound (bot app not installed for the user) and resourcematchfailed (Token Exchange URL doesn't match the Application ID URI). See SSO Setup - Troubleshooting for a full list of failure codes and troubleshooting steps.