Add authentication to a bot

APPLIES TO: yesSDK v4 no SDK v3

The Azure Bot Service v4 SDK facilitates the development of bots that can access online resources that require authentication. Your bot does not need to manage authentication tokens. Azure does it for you using OAuth2 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 does not 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 authentication, see Bot authentication.

Note

Authentication also works with BotBuilder v3. However, this article covers just the v4 sample code.

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

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

Web Chat and Direct Line considerations

Important

When you use Azure Bot Service authentication with Web Chat there are some important security considerations you must keep in mind. For more information, see the security considerations section in the REST authentication article.

Prerequisites

Sample BotBuilder version Demonstrates
Bot authentication in CSharp or JavaScript or Python v4 OAuthCard support
Bot authentication MSGraph in CSharp or JavaScript or Python v4 Microsoft Graph API support with OAuth 2

About the samples

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

  1. An Azure Active Directory (AD) application 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.
  2. A separate Azure AD application that functions 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 Azure AD application. However, this application secures channel-to-bot access. You need an additional Azure AD application for each external secured resource you want the bot to access on behalf of the user.

Create the Azure bot registration

This section shows how to register a bot resource with Azure to host the bot code.

  1. In your browser, navigate to the Azure portal.

  2. In the left panel, select create a new resource.

  3. In the right panel, search for resource types that include the word bot, and choose Bot Channels Registration.

  4. Click Create.

  5. In the Bot Channels Registration panel, enter the required information. The following picture shows an example.

    bot channels registration

  6. Click Auto create App ID and password and select Create New.

  7. Click Create App ID in the App Registration Portal. This will open a new page.

  8. In the App registration page, click New registration in the upper left.

  9. Enter the name of the bot application you are registering. This article uses TestingBotAuth for the name, but each bot needs a unique name.

  10. For Supported account types select Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox).

  11. Click Register. Once completed, Azure displays an overview page for the app registration.

  12. Copy the Application (client) ID and save it to a file.

  13. In the left panel, click Certificate & secrets.

    1. Under Client secrets, click New client secret.
    2. Add a description to identify this secret from others you might need to create for this app.
    3. Set Expires to Never.
    4. Click Add.
    5. Copy the your new client secret and save it to a file.

      Warning

      Record the secret just long enough to get the bot set up. Do not keep a copy of it around unless you have a good reason, in this case, keep it in safe place.

  14. Go back to the Bot Channel Registration window and copy the App ID and the Client secret in the Microsoft App ID and Password boxes, respectively.

  15. Click OK.

  16. Finally, click Create.

After Azure has completed the registration, the bot channels registration and the bot app service will be included in the resource group you selected.

Azure AD identity service

The Azure Active Directory (Azure AD) is a cloud identity service that allows you to build applications that securely sign in users using industry standard protocols like OAuth2.0.

You can use one of these two identity services:

  1. Azure AD 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 Azure Active Directory for developers (v1.0) overview.
  2. Microsoft identity platform (v2.0). Also known as the Azure AD v2 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 Azure Active Directory for developers).

Create the Azure AD identity application

This section shows how to create an Azure AD identity application that uses OAuth2 to authenticate the bot. You can use Azure AD v1 or Azure AD v2 endpoints.

Tip

You will need to create and register the Azure AD application in a tenant in which you can consent to delegate permissions requested by an application.

  1. Open the Azure Active Directory panel in the Azure portal. If you are not in the correct tenant, click Switch directory to switch to the correct tenant. (For instruction on creating a tenant, see Access the portal and create a tenant.)

  2. Open the App registrations panel.

  3. In the App registrations panel, click 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

      1. Select Web.
      2. Set the URL to https://token.botframework.com/.auth/web/redirect.
    4. Click Register.

      • Once it is created, Azure displays the Overview page for the app.
      • Record the Application (client) ID value. You will use this value later as the Client id when you register your Azure AD application with your bot.
      • Also record the Directory (tenant) ID value. You will also use this to register this application with your bot.
  5. In the navigation pane, click Certificates & secrets to create a secret for your application.

    1. Under Client secrets, click 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. Set Expires to Never.
    4. Click Add.
    5. Before leaving this page, record the secret. You will use this value later as the Client secret when you register your Azure AD application with your bot.
  6. In the navigation pane, click API permissions to open the API permissions panel. It is a best practice to explicitly set the API permissions for the app.

    1. Click 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. Click Add permissions. (The first time a user accesses this app through the bot, they will need to grant consent.)

You now have an Azure AD application configured.

Register the Azure AD OAuth application with the bot

The next step is to register the Azure AD application that you just created with the bot.

Azure AD v2

  1. Navigate to your bot's Bot Channels Registration page on the Azure Portal.

  2. Click Settings.

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

  4. Fill in the form as follows:

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

    2. For Service Provider, select Azure Active Directory v2. Once you select this, the Azure AD-specific fields will be displayed.

    3. For Client id, enter the application (client) ID that you recorded for your Azure AD v1 application.

    4. For Client secret, enter the secret that you created to grant the bot access to the Azure AD app.

    5. For Tenant ID, enter the directory (tenant) ID that your recorded earlier for your AAD 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 Azure AD app if you selected Accounts in this organizational directory only (Microsoft only - Single tenant) enter the tenant ID you recorded earlier for the AAD app.
      • However, if you selected Accounts in any organizational directory (Any AAD directory - Multi tenant and personal Microsoft accounts e.g. Xbox, Outlook.com) or Accounts in any organizational directory(Microsoft Azure AD directory - Multi tenant) enter the word common instead of a tenant ID. Otherwise, the AAD app will verify through the tenant whose ID was selected and exclude personal MS accounts.

      This will be the tenant associated with the users who can be authenticated. For more information, see Tenancy in Azure Active Directory.

    6. For Scopes, enter the names of the permission you chose from application registration: Mail.Read Mail.Send openid profile User.Read User.ReadBasic.All.

      Note

      For Azure AD v2, Scopes field takes a case-sensitive, space-separated list of values.

  5. Click 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 is used for SSO in Azure AD v2 only.

Test your connection

  1. Click on the connection entry to open the connection you just created.
  2. Click 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. Click 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 will 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 MSGraph.

  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;.

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

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-click on the project and choose Publish), but it is 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 have not 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 have 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 is an increased security risk. This can be mitigated using the Direct Line enhanced security that allows the setting up of valid domains that are allowed to be authenticated.

See Connect a bot to Direct Line and Enhanced Direct Line Authentication Features.

  1. Run the bot sample locally on your machine.
  2. Start the emulator.
  3. You will 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 the bot channels registration information for your bot.

Bot authentication example

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

Sample output

Bot authentication MSGraph example

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

Sample output


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 Bot Service already has a token for the current user and connection. If there is a token, the token is returned.
  2. If Azure Bot Service does not have a cached token, an OAuthCard is created which is a sign in button the user can click on.
  3. After the user clicks on the OAuthCard sign in button, Azure Bot Service will either send the bot the user's token directly or will 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

Bot architecture

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 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 is 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 is best practice to let users explicitly sign out or logout, 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 bot adapter encapsulates the authentication processes.
            var botAdapter = (BotFrameworkAdapter)innerDc.Context.Adapter;
            await botAdapter.SignOutUserAsync(innerDc.Context, ConnectionName, null, cancellationToken);
            await innerDc.Context.SendActivityAsync(MessageFactory.Text("You have been signed out."), cancellationToken);
            return await innerDc.CancelAllDialogsAsync(cancellationToken);
        }
    }

    return null;
}

Adding Teams Authentication

Teams behaves somewhat differently than other channels in regards to OAuth and requires a few changes to properly implement authentication. We will add code from the Teams Authentication Bot sample (C#/JavaScript).

One difference between other channels and Teams is that Teams sends an invoke activity to the bot, rather than an event activity.

Bots/TeamsBot.cs

protected override async Task OnTeamsSigninVerifyStateAsync(ITurnContext<IInvokeActivity> turnContext, CancellationToken cancellationToken)
{
    Logger.LogInformation("Running dialog with signin/verifystate from an Invoke Activity.");

    // The OAuth Prompt needs to see the Invoke Activity in order to complete the login process.

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

If you use an OAuth prompt, this invoke activity must be forwarded to the dialog. We will do so in the TeamsActivityHandler. Add the following code to your main dialog file.

Bots/DialogBot.cs

public class DialogBot<T> : TeamsActivityHandler where T : Dialog

Finally, make sure to add an appropriate TeamsActivityHandler file (TeamsActivityHandler.cs for C# bots and teamsActivityHandler.js for Javascript bots) at the topmost level in your bot's folder.

The TeamsActivityHandler also sends message reaction activities. A message reaction activity references the original activity using the reply to ID field. This activity should also be visible through the Activity Feed in Microsoft Teams.

Note

You need to create a manifest and include token.botframework.com in the validDomains section; otherwise the OAuthCard Sign in button will not open the authentication window. Use the App Studio to generate your manifest.

Further reading