Add authentication to a bot

APPLIES TO: SDK v4

The Azure AI Bot Service v4 SDK facilitates the development of bots that can access online resources that require user authentication. Your bot doesn't need to manage authentication tokens because Azure does it for you using OAuth 2.0 to generate a token based on each user's credentials. Your bot uses the token generated by Azure to access those resources. In this way, the user doesn't have to provide ID and password to the bot to access a secured resource but only to a trusted identity provider.

For an overview of how the Bot Framework handles this kind of authentication, see User authentication.

This article references two samples. One shows how to obtain an authentication token. The other is more complex and shows how to access Microsoft Graph on behalf of the user. In both cases, you can use Azure AD v1 or v2 as an identity provider to obtain an OAuth token for the bot. This article covers how to:

  • Create an Azure Bot resource
  • Create the Microsoft Entra ID identity provider
  • Register the Microsoft Entra ID identity provider with the bot
  • Prepare the bot code

Once you finish this article, you'll have a bot that can respond to a few simple tasks. In the Microsoft Graph example, you can send an email, display who you are, and check recent emails. You don't need to publish the bot to test the OAuth features; however, the bot will need valid Azure app ID and password.

Note

The Bot Framework JavaScript, C#, and Python SDKs will continue to be supported, however, the Java SDK is being retired with final long-term support ending in November 2023. Only critical security and bug fixes within this repository will be undertaken.

Existing bots built with the Java SDK will continue to function.

For new bot building, consider using Power Virtual Agents and read about choosing the right chatbot solution.

For more information, see The future of bot building.

Web Chat and Direct Line considerations

Important

You need to use Direct Line with enhanced authentication enabled to mitigate security risks when connecting to a bot using the Web Chat control. For more information, see Direct Line enhanced authentication.

Prerequisites

  • Knowledge of bot basics, managing state, the dialogs library, and how to implement sequential conversation flow, and how to reuse dialogs.

  • Knowledge of Azure and OAuth 2.0 development.

  • Visual Studio 2017 or later for .NET.

  • Node.js for JavaScript.

  • Python 3.8+ for Python.

  • One of the samples listed below.

    Sample BotBuilder version Demonstrates
    Authentication in C# or JavaScript or Java or Python v4 OAuthCard support
    Authentication for Microsoft Graph in C# or JavaScript or Java or Python v4 Microsoft Graph API support with OAuth 2.0
    Authentication for Microsoft Teams in C# or JavaScript or Java or Python v4 Microsoft Graph API support with OAuth 2.0

    To run the samples referenced in this article, you need:

    • An Microsoft Entra ID application with which to register a bot resource in Azure. This application allows the bot to access an external secured resource, such as Microsoft Graph. It also allows the user to communicate with the bot via several channels such as Web Chat.
    • A separate Microsoft Entra ID application to function as the identity provider. This application provides the credentials needed to establish an OAuth connection between the bot and the secured resource. Notice that this article uses Active Directory as an identity provider. Many other providers are also supported.

Important

Whenever you register a bot in Azure, it gets assigned an Microsoft Entra ID application. However, this application secures channel-to-bot access. You need an additional Microsoft Entra ID application for each external secured resource you want the bot to access on behalf of the user.

Create the resource

Create the Azure Bot resource, which will allow you to register your bot with the Azure AI Bot Service.

Tip

New Web App Bot and Bot Channels Registration resources can't be created; however, any such existing resources that are configured and deployed will continue to work. Bots created from a VSIX or Yeoman template from SDK version 4.14.1.2 or later contain ARM templates that will generate an Azure Bot resource.

  1. Go to the Azure portal.

  2. In the right pane, select Create a resource.

  3. In the search box enter bot, then press Enter.

  4. Select the Azure Bot card.

    Select Azure bot resource

  5. Select Create.

  6. Enter values in the required fields and review and update settings.

    1. Provide information under Project details. Select whether your bot will have global or local data residency. Currently, the local data residency feature is available for resources in the "westeurope" and "centralindia" region. For more information, see Regionalization in Azure AI Bot Service.

      The project details settings for an Azure Bot resource

    2. Provide information under Microsoft App ID. Select how your bot identity will be managed in Azure and whether to create a new identity or use an existing one.

      The Microsoft app ID settings for an Azure Bot resource

  7. Select Review + create.

  8. If the validation passes, select Create.

  9. Once the deployment completes, select Go to resource. You should see the bot and related resources listed in the resource group you selected.

  10. If you don't already have the Bot Framework SDK, select Download from GitHub to learn how to consume the packages for your preferred language.

    Create bot in SDK

You're now ready to build your bot with the Bot Framework SDK.

Tip

When Azure creates a new single-tenant or multi-tenant Azure Bot resource with a new app ID, it also generates a password.

Bot identity information

Follow these steps to add identity information to your bot's configuration file. The file differs depending on the programming language you use to create the bot.

Important

The Java and Python versions of the Bot Framework SDK only support multi-tenant bots. The C# and JavaScript versions support all three application types for managing the bot's identity.

Language File name Notes
C# appsettings.json Supports all three application types for managing your bot's identity.
JavaScript .env Supports all three application types for managing your bot's identity.
Java application.properties Only supports multi-tenant bots.
Python config.py Only supports multi-tenant bots. Provide the identity properties as arguments to the os.environ.get method calls.

The identity information you need to add depends on the bot's application type. Provide the following values in your configuration file.

Only available for C# and JavaScript bots.

Property Value
MicrosoftAppType UserAssignedMSI
MicrosoftAppId The client ID of the user-assigned managed identity.
MicrosoftAppPassword Not applicable. Leave this blank for a user-assigned managed identity bot.
MicrosoftAppTenantId The tenant ID of the user-assigned managed identity.

To update your app service

If you have an existing App Service resource (web app) for your bot and your bot is a user-assigned managed identity application, you may need to update your bot's app service:

  1. Go to the App Service blade for your bot's web app.
  2. Under Settings, select Identity.
  3. On the Identity blade, select the User assigned tab and Add (+).
  4. On the Add user assigned managed identity blade:
    1. Select your subscription.

    2. For User assigned managed identities, select the managed identity for your bot. If the managed identity was auto-generated for you, it will have the same name as your bot.

    3. Select Add to use this identity for your bot.

      The App Service Identity blade with the managed identity for the bot selected.

To get your app or tenant ID

To get your bot's app or tenant ID:

  1. Go to the Azure Bot resource blade for your bot.
  2. Go to the bot's Configuration blade. From this blade, you can copy the bot's Microsoft App ID or App Tenant ID.

To generate a new password

Single-tenant and multi-tenant bots have an app secret or password that you need for some operations. Azure AI Bot Service hides your bot secret. However, the owner of the bot's App Service resource can generate a new password:

  1. Go to the Azure Bot resource blade for your bot.
  2. Go to the bot's Configuration blade.
  3. Select Manage, next to Microsoft App ID, to go to the Certificates + secrets blade for the app service.
  4. Follow the instructions on the blade to create a new client secret and record the value in a safe place.

Microsoft Entra ID identity service

The Microsoft Entra ID is a cloud identity service that allows you to build applications that securely sign in users using industry standard protocols like OAuth 2.0.

You can use one of these two identity services:

  1. Microsoft Entra ID developer platform (v1.0). Also known as the Azure AD v1 endpoint, which allows you to build apps that securely sign in users with a Microsoft work or school account. For more information, see the Microsoft Entra ID for developers (v1.0) overview.
  2. Microsoft identity platform (v2.0). Also known as the Microsoft Entra ID endpoint, which is an evolution of the Azure AD platform (v1.0). It allows you to build applications that sign in to all Microsoft identity providers and get tokens to call Microsoft APIs, such as Microsoft Graph, or other APIs that developers have built. For more information, see the Microsoft identity platform (v2.0) overview.

For information about the differences between the v1 and v2 endpoints, see Why update to Microsoft identity platform (v2.0)?. For complete information, see Microsoft identity platform (formerly Microsoft Entra ID for developers).

Create the Microsoft Entra ID identity provider

This section shows how to create an Microsoft Entra ID identity provider that uses OAuth 2.0 to authenticate the bot. You can use Azure AD v1 or Microsoft Entra ID endpoints.

Tip

You'll need to create and register the Microsoft Entra ID application in a tenant in which you can consent to delegate permissions requested by an application.

  1. Open the Microsoft Entra ID panel in the Azure portal. If you aren't in the correct tenant, select Switch directory to switch to the correct tenant. (For information on how to create a tenant, see Access the portal and create a tenant.)

  2. Open the App registrations panel.

  3. In the App registrations panel, select New registration.

  4. Fill in the required fields and create the app registration.

    1. Name your application.

    2. Select the Supported account types for your application. (Any of these options will work with this sample.)

    3. For the Redirect URI, select Web and set the URL to one of the supported OAuth redirect URLs.

    4. Select Register.

      • Once it's created, Azure displays the Overview page for the app.
      • Record the Application (client) ID value. You'll use this value later as the client ID when you create the connection string and register the Microsoft Entra ID provider with the bot registration.
      • Record the Directory (tenant) ID value. You'll use this value to register this provider application with your bot.
  5. In the navigation pane, select Certificates & secrets to create a secret for your application.

    1. Under Client secrets, select New client secret.
    2. Add a description to identify this secret from others you might need to create for this app, such as bot login.
    3. For Expires, choose a length of time after which the secret will expire.
    4. Select Add.
    5. Before leaving Certificates & secrets, record the secret. You'll use this value later as the client secret when you register your Microsoft Entra ID application with your bot.
  6. In the navigation pane, select API permissions to open the API permissions panel. It's a best practice to explicitly set the API permissions for the app.

    1. Select Add a permission to show the Request API permissions pane.

    2. For this sample, select Microsoft APIs and Microsoft Graph.

    3. Choose Delegated permissions and make sure the permissions you need are selected. This sample requires theses permissions.

      Note

      Any permission marked as ADMIN CONSENT REQUIRED will require both a user and a tenant admin to login, so for your bot tend to stay away from these.

      • openid
      • profile
      • Mail.Read
      • Mail.Send
      • User.Read
      • User.ReadBasic.All
    4. Select Add permissions. (The first time a user accesses this app through the bot, they'll need to grant consent.)

You now have an Microsoft Entra ID application configured.

Note

You'll assign the Application (client) ID and the Client secret, when you create the connection string and register the identity provider with the bot registration. See next section.

Register the Microsoft Entra ID identity provider with the bot

The next step is to register your identity provider with your bot.

  1. Open your bot's Azure Bot resource page in the Azure portal.

  2. Select Settings.

  3. Under OAuth Connection Settings near the bottom of the page, select Add Setting.

  4. Fill in the form as follows:

    1. Name. Enter a name for your connection. You'll use it in your bot code.

    2. Service Provider. Select Microsoft Entra ID to display Microsoft Entra ID-specific fields.

    3. Client id. Enter the application (client) ID you recorded for your Microsoft Entra ID identity provider.

    4. Client secret. Enter the secret you recorded for your Microsoft Entra ID identity provider.

      Tip

      If you want to use certificates, you can select the AAD v2 with Certificates provider. You'll need to give Bot Service Token Store (appid: 5b404cf4-a79d-4cfe-b866-24bf8e1a4921) the permission to get the certificate.

    5. Token Exchange URL. Leave it blank because it's used for SSO in Microsoft Entra ID only.

    6. Tenant ID. Enter the directory (tenant) ID that you recorded earlier for your Microsoft Entra ID app or common depending on the supported account types selected when you created the Azure DD app. To decide which value to assign, follow these criteria:

      • When creating the Microsoft Entra ID app, if you selected Accounts in this organizational directory only (Microsoft only - Single tenant), enter the tenant ID you recorded earlier for the Microsoft Entra ID app.
      • However, if you selected Accounts in any organizational directory (Any Microsoft Entra ID directory - Multi tenant and personal Microsoft accounts e.g. Xbox, Outlook.com) or Accounts in any organizational directory(Microsoft Entra ID directory - Multi tenant), enter common instead of a tenant ID. Otherwise, the Microsoft Entra ID app will verify through the tenant whose ID was selected and exclude personal Microsoft accounts.

      This will be the tenant associated with the users who can be authenticated. For more information, see Tenancy in Microsoft Entra ID.

    7. For Scopes, enter the names of the permission you chose from the application registration. For testing purposes, you can just enter: openid profile.

      Note

      For Microsoft Entra ID, Scopes field takes a case-sensitive, space-separated list of values.

  5. Select Save.

Note

These values enable your application to access Office 365 data via the Microsoft Graph API. Also, the Token Exchange URL should be left blank because it's used for SSO in Microsoft Entra ID only.

Test your connection

  1. Select on the connection entry to open the connection you created.
  2. Select Test Connection at the top of the Service Provider Connection Setting pane.
  3. The first time, this should open a new browser tab listing the permissions your app is requesting and prompt you to accept.
  4. Select Accept.
  5. This should then redirect you to a Test Connection to <your-connection-name> Succeeded page.

You can now use this connection name in your bot code to retrieve user tokens.

Prepare the bot code

You'll need your bot's app ID and password to complete this process.

  1. Clone from the GitHub repository the sample you want to work with: Bot authentication or Bot authentication for Microsoft Graph.

  2. Update appsettings.json:

    • Set ConnectionName to the name of the OAuth connection setting you added to your bot.

    • Set MicrosoftAppId and MicrosoftAppPassword to your bot's app ID and app secret.

      Depending on the characters in your bot secret, you may need to XML escape the password. For example, any ampersands (&) will need to be encoded as &amp;.

    {
      "MicrosoftAppType": "",
      "MicrosoftAppId": "",
      "MicrosoftAppPassword": "",
      "MicrosoftAppTenantId": "",
      "ConnectionName": ""
    }
    

    To use OAuth in bot with data-residency in public cloud, you must add the following configurations in your appsettings

    "OAuthUrl": "<Regional-OAuth-Uri>",
    "ToChannelFromBotOAuthScope": "https://api.botframework.com",
    "ToChannelFromBotLoginUrlTemplate": "https://api.botframework.com",
    "PublicAzureChannel": "https://api.botframework.com",
    "ToBotFromChannelOpenIdMetadataUrl": "https://login.botframework.com/v1/.well-known/openidconfiguration",
    "ToBotFromEmulatorOpenIdMetadataUrl": "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration",
    "ToBotFromChannelTokenIssuer": "https://api.botframework.com",
    "ToChannelFromBotLoginUrl": "https://login.microsoftonline.com/botframework.com",
    

    Where <Regional-OAuth-Url> is one of the following URIs:

    URI Description
    https://europe.api.botframework.com For public-cloud bots with data residency in Europe.
    https://unitedstates.api.botframework.com For public-cloud bots with data residency in the United States.
    https://india.api.botframework.com For public-cloud bots with data residency in India.
  3. Update Startup.cs:

    To use OAuth in non-public Azure clouds, like the government cloud, you must add the following code in the Startup.cs file.

    string uri = "<uri-to-use>";
    MicrosoftAppCredentials.TrustServiceUrl(uri);
    OAuthClientConfig.OAuthEndpoint = uri;
    
    

    Where <uri-to-use> is one of the following URIs:

    URI Description
    https://api.botframework.azure.us For United States government-cloud bots without data residency.
    https://api.botframework.com For public-cloud bots without data residency. This is the default URI and doesn't require a change to Startup.cs.

To obtain the Microsoft app ID and Microsoft app password values, see Get registration password.

Note

You could now publish this bot code to your Azure subscription (right-select on the project and choose Publish), but it's not necessary for this article. You would need to set up a publishing configuration that uses the application and hosting plan that you used when configuration the bot in the Azure portal.

Test the bot using the Emulator

If you haven't done so already, install the Bot Framework Emulator. See also Debug with the Emulator.

In order for the bot sample login to work you must configure the Emulator as shown in Configure the Emulator for authentication.

Testing

After you've configured the authentication mechanism, you can perform the actual bot sample testing.

Note

You may be asked to enter a magic code, because the way the bot sample is implemented. This magic code is part of the RFC#7636 and is there to add an extra security element. By removing the magic code, there's an increased security risk. This can be mitigated using Direct Line with enhanced authentication enabled. For more information, see Bot Framework enhanced authentication.

  1. Run the bot sample locally on your machine.
  2. Start the Emulator.
  3. You'll need to provide your bot's app ID and password when you connect to the bot.
    • You get the app ID and the password from the Azure app registration. These are the same values you assigned to the bot app in the appsettings.json or .env file. In the Emulator, you assign these values in the configuration file or the first time you connect to the bot.
    • If you needed to XML-escape the password in your bot code, you also need to do so here.
  4. Type help to see a list of available commands for the bot, and test the authentication features.
  5. Once you've signed in, you don't need to provide your credentials again until you sign out.
  6. To sign out, and cancel your authentication, type logout.

Note

Bot authentication requires use of the Bot Connector service. The service accesses information from your Azure Bot resource.

Authentication example

In the Bot authentication sample, the dialog is designed to retrieve the user token after the user is logged in.

Sample conversation with the authentication sample bot.

Authentication for Microsoft Graph example

In the Bot authentication for Microsoft Graph sample, the dialog is designed to accept a limited set of commands after the user is logged in.

Sample conversation with the Microsoft Graph authentication sample bot.


Additional information

When a user asks the bot to do something that requires the bot to have the user logged in, the bot can use an OAuthPrompt to initiate retrieving a token for a given connection. The OAuthPrompt creates a token retrieval flow that consists of:

  1. Checking to see if the Azure AI Bot Service already has a token for the current user and connection. If there's a token, the token is returned.
  2. If Azure AI Bot Service doesn't have a cached token, an OAuthCard is created which is a sign-in button the user can select on.
  3. After the user selects on the OAuthCard sign-in button, Azure AI Bot Service will either send the bot the user's token directly or present the user with a 6-digit authentication code to enter in the chat window.
  4. If the user is presented with an authentication code, the bot then exchanges this authentication code for the user's token.

The following sections describe how the sample implements some common authentication tasks.

Use an OAuth prompt to sign the user in and get a token

Architecture diagram for the C# sample.

Dialogs\MainDialog.cs

Add an OAuth prompt to MainDialog in its constructor. Here, the value for the connection name was retrieved from the appsettings.json file.

AddDialog(new OAuthPrompt(
    nameof(OAuthPrompt),
    new OAuthPromptSettings
    {
        ConnectionName = ConnectionName,
        Text = "Please Sign In",
        Title = "Sign In",
        Timeout = 300000, // User has 5 minutes to login (1000 * 60 * 5)
    }));

Within a dialog step, use BeginDialogAsync to start the OAuth prompt, which asks the user to sign in.

  • If the user is already signed in, this will generate a token response event, without prompting the user.
  • Otherwise, this will prompt the user to sign in. The Azure AI Bot Service sends the token response event after the user attempts to sign in.
return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);

Within the following dialog step, check for the presence of a token in the result from the previous step. If it's not null, the user successfully signed in.

// Get the token from the previous step. Note that we could also have gotten the
// token directly from the prompt itself. There is an example of this in the next method.
var tokenResponse = (TokenResponse)stepContext.Result;

Wait for a TokenResponseEvent

When you start an OAuth prompt, it waits for a token response event, from which it will retrieve the user's token.

Bots\AuthBot.cs

AuthBot derives from ActivityHandler and explicitly handles token response event activities. Here, we continue the active dialog, which allows the OAuth prompt to process the event and retrieve the token.

protected override async Task OnTokenResponseEventAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
{
    Logger.LogInformation("Running dialog with Token Response Event Activity.");

    // Run the Dialog with the new Token Response Event Activity.
    await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
}

Log the user out

It's best practice to let users explicitly sign out, instead of relying on the connection to time out.

Dialogs\LogoutDialog.cs

private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken = default(CancellationToken))
{
    if (innerDc.Context.Activity.Type == ActivityTypes.Message)
    {
        var text = innerDc.Context.Activity.Text.ToLowerInvariant();

        if (text == "logout")
        {
            // The UserTokenClient encapsulates the authentication processes.
            var userTokenClient = innerDc.Context.TurnState.Get<UserTokenClient>();
            await userTokenClient.SignOutUserAsync(innerDc.Context.Activity.From.Id, ConnectionName, innerDc.Context.Activity.ChannelId, cancellationToken).ConfigureAwait(false);

            await innerDc.Context.SendActivityAsync(MessageFactory.Text("You have been signed out."), cancellationToken);
            return await innerDc.CancelAllDialogsAsync(cancellationToken);
        }
    }

    return null;
}

Adding Teams Authentication

OAuth is handled differently in Teams than in other channels. The Teams Authentication Bot sample (in C#, JavaScript, Java, or Python) demonstrates how to properly implement authentication for Teams.

Further reading