Get refresh tokens of Microsoft Graph API with OAuthPrompt - botframework

I'm creating a MS Teams bot which periodically checks the users' Outlook calendar by background threads spawned after the user logs in via OAuthPrompt.
To implement the feature, it seems that I have to configure an OAuth connection setting and an app registration supporting offline_access. Then, get a refresh token when getting an access token, according to Get access on behalf of a user.
But as long as I tried the example bot, the result of OAuthPrompt doesn't contain a refresh token. And I couldn't find the documented way to get it.
How can I achieve the goal? Do I need some hack on OAuthPrompt or some related classes? Do I have to build cards from scratch?

I concluded that we can't get refresh_token with OAuthPrompt from investigation. So I made up with a different way to achieve the goal.
The key idea is creating a tiny web app just for the "Sign in with Microsoft account" feature, which can easily get refresh_token as ordinary web apps.
Here is the example app: https://github.com/igrep/example-teams-bot-with-ms-account-refresh-token

The sample which you are using is for most of the channels, but Teams behaves differently. An Invoke Activity is sent to the bot rather than the Event Activity used by other channels. This Invoke Activity must be forwarded to the dialog if the OAuthPrompt is being used.
Refer to this documentation for adding authentication to your MS Teams bot, which makes use of Teams-auth sample.
For a better understanding of how OAuth works in MS Teams, you can refer to this documentation which explains the authentication flow.
Hope this helps!!

alwaysPrompt flag should be false. Then OAuth prompt will get refresh tokens silently without prompting login card.
Please refer the answer on github about this isse.
Bot composer OAuth refresh token

Another idea has flashed into my mind while writing this comment: running a dialog including OAuthPrompt in a TurnContext made with a ConversationRefrence, which is saved and passed to the background thread, may work. (But I have no time and no motive to try!)

In my case, I needed the refresh_token to get access tokens for other Microsoft resources like Exchange,
the solution was to use
const tokenResponses = await context.adapter.getAadTokens(context, this.connectionName, [
"https://outlook.office365.com",
"https://graph.microsoft.com",
]);

Related

Single Sign On(-ish) behavior from MS Teams with BotFramework Composer

We are using BotFramework Composer to create bots. These bots are supposed to get information from a backend REST service, where we need to know, which user is submitting the request for data. We are currently using {turn.activity.from.id} to get the Teams user's id, and sending it in a special http header in the "Send an HTTP request" action. We then perform a mapping of this id to our internal users.
We are, of course, aware, that this is not secure at all, since anyone who knows this, could get the user's id and send it to our service. We are currently thinking along the lines of generating a short-lived jwt token in the Bot to send to our application. However, we see no direct way of implementing this token generation in the Bot Framework Composer itself.
Also, we don't want to use OAuth, because we don't want the user to have to log in via the bot.
Is there a way to implement custom token generation using C# or js and assigning it to a dialog variable to be used in a "Send an HTTP request" action?
This document discusses how to implement an HTTP request in Composer. The first half is focused on creating a login for OAuth, which I know is not your focus, so look at the second half. If you set up a simple server that can generate a token for you, then you can make a request to it from Composer using the method described.
As links can break and docs can change (and Composer is still in Preview), I would recommend saving the doc somewhere and checking back every so often for any updates.
I've used HTTP requests from within Composer, myself, so I know this will work for you.
Hope of help!
You can create a custom Action or a package component and create any c# methods there for JWT generation. This will keep it all local to the bot.
https://learn.microsoft.com/en-us/composer/how-to-create-custom-actions

Microsoft Teams App - how to create events in Outlook calendar?

Is there a way to schedule Outlook calendar events from an MS Teams app?
As I understand, Microsoft Graph API would be an option. However, users would need to authenticate twice to use that (once when logging in to Teams, and once to get the token).
Yes, you're correct, on both points. Graph is the best way to go on this, and you would need to authenticate, unfortunately. It's not Teams the user is authenticating to, per se, it's -your app- that's needing to get a token in order to operate on the user's behalf.
For a Bot, your best option is the Signin Card, but for a Tab it's possible to do a "silent" authentication.
#nagy.zsolt.hun, unfortunately there is no other way. You have to implement authentication. Well the Silent authentication can reduce your repetitive login's as #Hilton Giesenow mentioned.

AAD Authentication Directline & Teams, Disable Security Code

I would like to have users authenticated in a v4 bot in both Teams and Directline (rendered on webpage) with as little user interaction as possible. My code is based on MS BOT Samples Github: BotAuthenticationMSGraph and has not changed at all besides configuration settings.
Right now, the directline pops up an extra tab, if needed presents username/password signin, and always presents six digit code for the user to copy/paste into the chat window. This completes authentication.
Right now, on teams, the operation is the same aside from a problem where after entering credentials (if needed), the popup then closes before the code can be seen. However, if I complete the process manually in a browser, pasting the code into teams successfully completes the signin.
How can I disable the need for a six digit code? Additionally, if anyone knows a fix to prevent the teams signin popup from closing early let me know.
You can make use of OAuthCards for authentication in Microsoft Teams.
https://github.com/Microsoft/BotFramework-WebChat/issues/1001#issuecomment-434530463 is a solution which involves webchat which works with AAD and no magic code.
https://github.com/Microsoft/BotBuilder/issues/4632#issuecomment-441957719( refer to #compulim's comment here, who is the developer of Web Chat and has specified the steps to eliminate the magic code flow).
Additionally, this explains about the mechanism that’s both more secure and users do not need to deal with any “magic code”.
Also, If your browser is set to block 3rd party cookies, it will again fall back to the magic code flow.
With regards to your last question about the teams signin popup closing early, refer to this GitHub issue which deals with a similar issue.
Hope this helps.

How to perform Graph auth without hosting my bot in Azure?

From my understanding, the OAuthPrompt requires a connection name. To create this, I need to make use of the Bot Channels Registration (as per the documentation). However, this seems to require me to create an Azure account and enter my payment card details. I would like to avoid entering my details if possible as I would not like to be charged for using any Azure services. Is there any way to avoid this?
If I must manually handle the OAuth process, I would like my sign-in to pop up in a small window like the "Allow" button triggers within the Who bot. I have tried SignIn cards which I have read just don't work in teams, and I have also tried OpenUrl type actions in a card which, when pressed, open the URL in my browser as opposed to a pop-up. How can I achieve this?
You can create a Bot Framework bot (only for Microsoft Teams) using the guidance here: https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/bots/bots-create. To summarize that article, you can use this endpoint to create a non-Azure bot: https://dev.botframework.com/bots/new
If you chose to use the Azure Bot Framework, you will not be charged for the Bot Framework if Microsoft Teams is your only channel (this does NOT include your web service if you chose to host your bot code on Azure, although you can chose a free tier to avoid any charges).
For authentication, see this section of the MS Teams documentation: https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/authentication/authentication. Depending on how you chose to implement your authentication, there are a few articles in that section that may apply. The OAuth card does work in Teams (not the free version, does not work with guest accounts, and only works for Azure bots).
For authentication, if you're redirecting to a different domain make sure you add it to the validDomains in your app manifest.

Invoking Deep Link from Cortana with authentication

I'm trying to get my Cortana Skill (from a Web based Bot) to play a specific album on Groove.
Playing the album can be achieved with a Deep Link like this one, although if you try it you will probably just launch the Windows Store.
That happens because that link requires you to be authenticated in the music.microsoft.com endpoint. But invoking the Deep Link from Cortana's LaunchUri laves no room for setting an Authorization header, so there's really no way to guarantee that the user will be have previously authentified.
Is it possible to make this work seamlessly by persisting the auth token and passing it through Cortana somehow?

Resources