Bot Authentication in the Bot Framework

About a year ago, my colleague and resident bot wizard, Mat Velloso built a .net package for bots authenticating and calling services secured by Azure Active Directory (such as the Microsoft Graph). As Mat's AuthBot gained momentum, Mat and I discussed how we could improve and move it forward. We decided on the following:

  • Support more authentication providers beyond just Azure AD
  • Remove platform-specific dependencies on ADAL and MSAL
  • Make it easier to implement in a bot framework project
  • Align package naming with Bot Framework packages and similar efforts in Node.js

As a response to these goals, I am pleased to introduce the BotAuth package. BotAuth uses a provider model that is dependency injected into the core authentication logic. It support virtually any OAuth2 provider with providers already available for AAD v1, v2, B2C, and anything supported by the OAuth2 .net package (which includes Facebook, Google, LinkedIn, Yahoo, etc). Unlike the original AuthBot package, BotAuth does not have any provider-specific dependencies, all dependencies are injected into BotAuth when invoked through a bot dialog.

BotAuth is more aligned with the dialog model of the BotBuilder SDK. You simply forward the bot dialog to the BotAuth (with the appropriate provider and settings) and BotAuth will return an access token to that provider. It is very similar to a javascript promises approach and detailed later in this post. All of the bot framework packages are prefixed with "bot"…BotFramework-Emulator, BotBuilder, BotFramework-WebChat. Additionally, there is a popular bot authentication package in node.js effort called BotAuth. As such, the new package was named to align with these.

Using BotAuth

To use BotAuth, you should install the NuGet package of the provider(s) you want to use (NuGet packages reference below). Currently, BotAuth has providers for Azure AD v1, v2, and B2C applications as well as a generic OAuth2 provider that supports a number of other identities (Facebook, Google, LinkedIn, etc). BotAuth is invoked by initializing an instance of AuthenticationOptions with your app details and passing that into the AuthDialog with a provider instance (implementing IAuthProvider). The AuthDialog returns an access token when the dialog resumes. Although you could cache the returned access token in your own app, the benefit of always going through the AuthDialog is that it manages token cache automatically and will prompt for authentication when necessary. In the sample below, the MSALAuthProvider is used, which is a provider for Azure AD v2 applications.

Invoking BotAuth in BotBuilder Dialog

 public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> item)
{
    var message = await item;

    // Initialize AuthenticationOptions and forward to AuthDialog for token
    AuthenticationOptions options = new AuthenticationOptions()
    {
        Authority = ConfigurationManager.AppSettings["aad:Authority"],
        ClientId = ConfigurationManager.AppSettings["aad:ClientId"],
        ClientSecret = ConfigurationManager.AppSettings["aad:ClientSecret"],
        Scopes = new string[] { "User.Read" },
        RedirectUrl = ConfigurationManager.AppSettings["aad:Callback"]
    };
            
    await context.Forward(new AuthDialog(new MSALAuthProvider(), options), async (IDialogContext authContext, IAwaitable<AuthResult> authResult) =>
    {
        var result = await authResult;

        // Use token to call into service
        var json = await new HttpClient().GetWithAuthAsync(result.AccessToken, "https://graph.microsoft.com/v1.0/me");
        await authContext.PostAsync($"I'm a simple bot that doesn't do much, but I know your name is {json.Value<string>("displayName")} and your UPN is {json.Value<string>("userPrincipalName")}");
    }, message, CancellationToken.None);
}

Samples

The BotAuth repo contains samples for all of the providers plus a multi-provider sample. Additionally, there are two Azure AD v2 samples for building Microsoft Graph enabled bots that can be cloned into your own project. One is a very basic bot and the other is a bot leveraging LUIS.

Azure AD v1 Sample Azure AD v2 Sample Azure AD B2C Sample Generic OAuth2 Sample Multi-provider Sample Basic Microsoft Graph Sample Microsoft Graph Sample with LUIS

Building a Provider

To build a custom provider, you most install the BotAuth core package into your project and create a class that implements the IAuthProvider interface. This interface has 4 functions and a property you need to implement so the provider can be dependency injected into the BotAuth core library at runtime. Refer to the existing providers if you want more information on how to implement this interface.

Conclusion

This is the first release of BotAuth, so we are eager to get feedback and new contributors to the project. The best way to provide feedback it by submitted an issue (or pull-request) to the repo.

BotAuth Repo on GitHub Azure AD v1 NuGet Package Azure AD v2 NuGet Package Azure AD B2C NuGet Package Generic OAuth2 Package