APPLIES TO: SDK v4
At times a bot must access secured online resources on behalf of the user, such as checking email, checking on flight status, or placing an order. The user must authorize the bot to do so on their behalf, and in order to authorize the bot, the user must authenticate their identity. OAuth is used to authenticate the user and authorize the bot. See also Authentication types.
If you want to refresh your OAuth knowledge, see the following:
User authentication in a conversation
To perform certain operations on behalf of a user, such as checking email, referencing a calendar, checking on flight status, or placing an order, the bot will need to call an external service, such as the Microsoft Graph, GitHub, or a company's REST service. Each external service has a way of securing those calls. A common way to issue those requests is to use a user token that uniquely identifies the user on that external service (sometimes referred to as a JSON Web Token (JWT)).
To secure the call to an external service, the bot must ask the user to sign-in, so it can acquire the user's token for that service. Many services support token retrieval via the OAuth or OAuth2 protocol.
The Azure Bot Service provides specialized sign-in cards and services that work with the OAuth protocol and manage the token life-cycle. A bot can use these features to acquire a user token.
As part of bot configuration, an OAuth connection is registered within the Azure Bot Service resource in Azure.
The connection contains information about the identity provider to use, along with a valid OAuth client ID and secret, the OAuth scopes to enable, and any other connection metadata required by that identity provider.
In the bot's code, the OAuth connection is used to help sign-in the user and get the user token.
The following image shows the elements involved in the authentication process.
About the Bot Framework Token Service
The Bot Framework Token Service is responsible for:
- Facilitating the use of the OAuth protocol with a wide variety of external services.
- Securely storing tokens for a particular bot, channel, conversation, and user.
- Acquiring user tokens.
If the bot has an expired user token, the bot should:
- Log the user out
- Initiate the sign in flow again
For example, a bot that can check a user's recent emails, using the Microsoft Graph API, requires a user token from an Identity Provider, in this case Azure Active Directory. At design time, the bot developer performs these two important steps:
- Registers an Azure Active Directory application, an Identity Provider, with the Bot Framework Token Service, via the Azure Portal.
- Configures an OAuth connection (named for example
GraphConnection) for the bot.
The following picture shows the time sequence of the user's interaction with a bot when an email request is made using the Microsoft Graph service.
The user makes an email request to the bot.
An activity with this message is sent from the user to the Bot Framework channel service. The channel service ensures that the
useridfield within the activity has been set and the message is sent to the bot.
User ID's are channel specific, such as the user's Facebook ID or their SMS phone number.
The bot makes a request to the Bot Framework Token Service asking if it already has a token for the UserId for the OAuth connection
Since this is the first time this user has interacted with the bot, the Bot Framework Token Service does not yet have a token for this user, and returns a NotFound result to the bot.
If the token is found, the authentication steps are skipped and the bot can make the email request using the stored token.
The bot creates an OAuthCard with a connection name of
GraphConnectionand replies to the user asking to sign-in using this card.
The activity passes through the Bot Framework Channel Service, which calls into the Bot Framework Token Service to create a valid OAuth sign-in URL for this request. This sign-in URL is added to the OAuthCard and the card is returned to the user.
The user is presented with a message to sign-in by clicking on the OAuthCard's sign-in button.
When the user clicks the sign-in button, the channel service opens a web browser and calls out to the external service to load its sign-in page.
The user signs-in to this page for the external service. Then the external service completes the OAuth protocol exchange with the Bot Framework Token Service, resulting in the external service sending the Bot Framework Token Service the user token. The Bot Framework Token Service securely stores this token and sends an activity to the bot with this token.
The bot receives the activity with the token and is able to use it to make calls against the MS Graph API.
Securing the sign-in URL
An important consideration when the Bot Framework facilitates a user login is how to secure the sign-in URL. When a user is presented with a sign-in URL, this URL is associated with a specific conversation ID and user ID for that bot. This URL should not be shared, as it would cause the wrong sign-in to occur for a particular bot conversation. To mitigate security attacks regarding sharing the sign-in URL, it is necessary to ensure that the machine and person who clicks on the sign-in URL is the person who owns the conversation window.
Some channels such as Microsoft Teams, Direct Line, and WebChat are able to do this without the user noticing. For example, WebChat uses session cookies to ensure that the sign-in flow took place in the same browser as the WebChat conversation. However, for other channels the user is often presented with a 6-digit magic code. This is similar to a built-in multi-factor authentication, as the Bot Framework Token Service will not release the token to the bot unless the user finishes the final authentication, proving that the person who signed-in has access to the chat experience by entering the 6-digit code.
Please, keep in mind these important Security considerations. You can find additional information in this blog post: Using WebChat with Azure Bot Service Authentication.
Now that you know about user authentication, let's take a look at how to apply that to your bot.