diff --git a/msteams-platform/TOC.yml b/msteams-platform/TOC.yml index 13334cb8678..eace571bbc7 100644 --- a/msteams-platform/TOC.yml +++ b/msteams-platform/TOC.yml @@ -69,7 +69,7 @@ href: ./concepts/authentication/auth-bot-AAD - name: Silent authentication and SSO href: ./concepts/authentication/auth-silent-AAD - - name: Configuring authentication providers + - name: Configuring identity providers href: ./concepts/authentication/auth-configure - name: Activity Feed href: ./concepts/activity-feed diff --git a/msteams-platform/assets/images/authentication/Tab_auth_sequence_diagram.png b/msteams-platform/assets/images/authentication/Tab_auth_sequence_diagram.png deleted file mode 100644 index 340b961a0b5..00000000000 Binary files a/msteams-platform/assets/images/authentication/Tab_auth_sequence_diagram.png and /dev/null differ diff --git a/msteams-platform/assets/images/authentication/bot_auth_sequence_diagram.png b/msteams-platform/assets/images/authentication/bot_auth_sequence_diagram.png index f0333343ecb..aba3b2453a8 100644 Binary files a/msteams-platform/assets/images/authentication/bot_auth_sequence_diagram.png and b/msteams-platform/assets/images/authentication/bot_auth_sequence_diagram.png differ diff --git a/msteams-platform/assets/images/authentication/tab_auth_sequence_diagram.png b/msteams-platform/assets/images/authentication/tab_auth_sequence_diagram.png new file mode 100644 index 00000000000..d7f0096309d Binary files /dev/null and b/msteams-platform/assets/images/authentication/tab_auth_sequence_diagram.png differ diff --git a/msteams-platform/concepts/authentication/Sequence Diagrams.vsdx b/msteams-platform/concepts/authentication/Sequence Diagrams.vsdx index 32ed2729df7..6b0c618cb1a 100644 Binary files a/msteams-platform/concepts/authentication/Sequence Diagrams.vsdx and b/msteams-platform/concepts/authentication/Sequence Diagrams.vsdx differ diff --git a/msteams-platform/concepts/authentication/auth-bot-AAD.md b/msteams-platform/concepts/authentication/auth-bot-AAD.md index ecfff078e10..793d2068ca4 100644 --- a/msteams-platform/concepts/authentication/auth-bot-AAD.md +++ b/msteams-platform/concepts/authentication/auth-bot-AAD.md @@ -2,7 +2,7 @@ title: Authentication for bots using Azure Active Directory description: Describes AAD authentication in Teams and how to use it in your bots keywords: teams authentication bots AAD -ms.date: 02/28/2018 +ms.date: 03/01/2018 --- # Authenticate a user in a Microsoft Teams bot @@ -14,116 +14,106 @@ The authentication flow described in this article is very similar to that of tab For a general overview of authentication flow for bots see the topic [Authentication flow in bots](~/concepts/authentication/auth-flow-bot). -## Configure an authentication provider +## Configuring identity providers -See the topic [Configure an authentication provider](~/concepts/authentication/auth-configure) for detailed steps on configuring Azure Active Directory for authentication. +See the topic [Configure identity providers](~/concepts/authentication/configure-AAD) for detailed steps on configuring OAuth 2.0 callback redirect URL(s) when using Azure Active Directory as an identity provider. ## Initiate authentication flow -Usually authentication flow is triggered by a user action. You should not drive the authentication pop-up automatically because this is likely to trigger the browser's pop-up blocker as well as confuse the user. +Authentication flow should be triggered by a user action. You should not open the authentication pop-up automatically because this is likely to trigger the browser's pop-up blocker as well as confuse the user. ## Add UI to start authentication -Add UI to the bot to enable the user to sign in when needed. Here it is done from the bot's hero card. +Add UI to the bot to enable the user to sign in when needed. Here it is done from a Thumbnail card, in TypeScript: ```TypeScript -let buttons = new Array(); -buttons.push(new builder.CardAction(session) - .type("signin") - .title("Sign In") - .value(config.get("app.baseUri") + "/bot-auth/simple-start?width=5000&height=5000"), -); - -let messageBackButton = builder.CardAction.messageBack(session, JSON.stringify({ action: "getProfile" }), "Get Profile") - .displayText("Get Profile") - .text(Strings.messageBack_button_text); // this matches match for MessageBackReceiverDialog -buttons.push(messageBackButton); - -let messageBackButton2 = builder.CardAction.messageBack(session, JSON.stringify({ action: "signout" }), "Sign Out") -.displayText("Sign Out") -.text(Strings.messageBack_button_text); // this matches match for MessageBackReceiverDialog -buttons.push(messageBackButton2); - +// Show prompt of options +protected async promptForAction(session: builder.Session): Promise { + let msg = new builder.Message(session) + .addAttachment(new builder.ThumbnailCard(session) + .title(this.providerDisplayName) + .buttons([ + builder.CardAction.messageBack(session, "{}", "Sign in") + .text("SignIn") + .displayText("Sign in"), + builder.CardAction.messageBack(session, "{}", "Show profile") + .text("ShowProfile") + .displayText("Show profile"), + builder.CardAction.messageBack(session, "{}", "Sign out") + .text("SignOut") + .displayText("Sign out"), + ])); + session.send(msg); +} ``` -Three buttons have been added to the Hero Card: Sign in, Get Profile, and Sign Out. +Three buttons have been added to the Hero Card: Sign in, Show Profile, and Sign out. ## Sign the user in -selecting the Sign in button generates an event that is handled in `getInvokeHandler` using this code: - -```TypeScript -if ((event as any).name === "signin/verifyState") { - let aadApi = new AADRequestAPI(); - let response = await aadApi.getAsync("https://graph.microsoft.com/v1.0/me/", { Authorization: " Bearer " + (event as any).value.state.accessToken }, null); - - let info = JSON.parse(response); - - session.send(info.displayName + "
" + info.mail + "
" + info.officeLocation); - - callback(null, "", 200); - return; -} -``` - -Here the bot makes a call to the `me` Graph endpoint with the token it gets from the invoke payload. Graph responds with the user information for the person who logged in. The response is then parsed and specific parts of it are sent to the chat session. +Because of the validation that must be performed for security reasons and the support for the mobile versions of Teams, the code isn't shown here, but [here's an example of the code that kicks off the process when the user presses the Sign in button.](https://github.com/OfficeDev/microsoft-teams-sample-auth-node/blob/e84020562d7c8b83f4a357a4a4d91298c5d2989d/src/dialogs/BaseIdentityDialog.ts#L154-L195). -### Notes +The validation and mobile support are explained in the topic [Authentication flow in bots](~/concepts/authentication/auth-flow-bot). -Authentication flow must start on a page that's on your domain; don't start it by going directly to your identity provider's login or consent page. In this example, even though we're using Azure AD, we begin at `/tab-auth/simple-start` rather than going directly to the Graph endpoint at `https://graph.microsoft.com/v1.0/me/`. If you skip this step, the login popup may fail to close when you call `notifySuccess()` or `notifyFailure()`. +Be sure to add the domain of your authentication redirect URL to the [`validDomains`](~/resources/schema/manifest-schema#validdomains) section of the manifest. If you don't, the login popup will not appear. -Add the domain of your authentication redirect URL to the [`validDomains`](~/resources/schema/manifest-schema#validdomains) section of the manifest. Failure to do so might result in an empty pop-up. +## Showing user profile information -## Get the users profile - -When the user selects the `Get Profile` button in the Hero card the following code is executed. +Although getting an access token is difficult because of all the transitions back and forth across different websites and the security issues that must be addressed, once you have a token, obtaining information from Azure Active Directory is straightforward. The bot makes a call to the `me` Graph endpoint with the access token. Graph responds with the user information for the person who logged in. Information from the response is used to construct a bot card and sent. ```TypeScript -case "getProfile": - // See if we have an AAD token - const graphResource = "https://graph.microsoft.com"; - let aadTokens = session.userData.aadTokens || {}; - let graphToken = aadTokens[graphResource] as TokenResponse; - - if (!graphToken) { - // We don't have a Graph token for the user, ask them to sign in - session.send(new builder.Message(session) - .addAttachment(new builder.HeroCard(session) - .text("You're not yet signed in. Please click on the Sign In button to log in.") - .buttons([ - new builder.CardAction(session) - .type("signin") - .title("Sign In") - .value(config.get("app.baseUri") + "/bot-auth/simple-start?width=5000&height=5000"), - ]))); +// Show user profile +protected async showUserProfile(session: builder.Session): Promise { + let azureADApi = this.authProvider as AzureADv1Provider; + let userToken = this.getUserToken(session); + + if (userToken) { + let profile = await azureADApi.getProfileAsync(userToken.accessToken); + let profileCard = new builder.ThumbnailCard() + .title(profile.displayName) + .subtitle(profile.mail) + .text(`${profile.jobTitle}
${profile.officeLocation}`); + session.send(new builder.Message().addAttachment(profileCard)); } else { - // Use the Graph token to get the basic profile - try { - let requestHelper = new AADRequestAPI(); - let response = await requestHelper.getAsync("https://graph.microsoft.com/v1.0/me/", { Authorization: "Bearer " + graphToken.access_token }, null); - - let info = JSON.parse(response); - session.send(info.displayName + "
" + info.mail + "
" + info.officeLocation); - } catch (e) { - console.log(e); - session.send("There was an error getting the user's profile."); - } + session.send("Please sign in to AzureAD so I can access your profile."); } + + await this.promptForAction(session); +} + +// Helper function to make the Graph API call +public async getProfileAsync(accessToken: string): Promise { + let options = { + url: "https://graph.microsoft.com/v1.0/me", + json: true, + headers: { + "Authorization": `Bearer ${accessToken}`, + }, + }; + return await request.get(options); +} ``` -If the user is not signed in they are prompted to do so now. Otherwise basic information is obtained from Graph. +If the user is not signed in they are prompted to do so. ## Sign the user out ```TypeScript -case "signout": - session.userData.aadTokens = {}; - session.send("Ok, I've cleared your tokens."); - break; +// Handle user logout request +private async handleLogout(session: builder.Session): Promise { + if (!utils.getUserToken(session, this.providerName)) { + session.send(`You're already signed out of ${this.providerDisplayName}.`); + } else { + utils.setUserToken(session, this.providerName, null); + session.send(`You're now signed out of ${this.providerDisplayName}.`); + } + + await this.promptForAction(session); +} ``` ## Other samples For sample code showing the bot authentication process see: -* [Microsoft Teams bot authentication sample](https://github.com/OfficeDev/microsoft-teams-sample-auth-node) \ No newline at end of file +* [Microsoft Teams bot authentication sample](https://github.com/OfficeDev/microsoft-teams-sample-auth-node) diff --git a/msteams-platform/concepts/authentication/auth-configure.md b/msteams-platform/concepts/authentication/auth-configure.md index eaf11672f09..c6225b667c4 100644 --- a/msteams-platform/concepts/authentication/auth-configure.md +++ b/msteams-platform/concepts/authentication/auth-configure.md @@ -1,18 +1,18 @@ --- -title: Configure an authentication provider -description: Describes how to configure an authentication provider -keywords: teams authentication AAD -ms.date: 02/28/2018 +title: Configuring OAuth 2.0 identity providers +description: Describes how to configure identity providers with a focus on AAD +keywords: teams authentication AAD oauth identity provider +ms.date: 03/01/2018 --- -# Configure an authentication provider +# Configuring identity providers -## Configure Azure Active Directory for authentication +## Configuring an application to use Azure Active Directory as an identity provider -Most service providers require you to register your application with their service before you can authenticate and consume service resources. To do this with AAD follow these steps: +Identity providers supporting OAuth 2.0 will not authenticate requests from unknown applications; applications must be registered ahead of time. To do this with AAD, follow these steps: 1. Open the [Application Registration Portal](https://apps.dev.microsoft.com/), click on *Add an app* and follow the steps to register your app. If your app has already been registered (for example if you have previously registered a bot in your app) locate your app. -2. Select your app to view it's properties. Find the *Platforms* section for the app and select *Add Platform*. +2. Select your app to view its properties. Find the *Platforms* section for the app and select *Add Platform*. ![View team](~/assets/images/authentication/AppRegistration.png) @@ -24,16 +24,16 @@ Most service providers require you to register your application with their servi ![View team](~/assets/images/authentication/Platforms.png) - Add the redirect and logout URLs in the Web section of Platforms. For the TypeScript/Node.js and C# sample apps on GitHub, the redirect URLs will be similar to this: + Add the OAuth 2.0 redirect and logout URLs in the Web section of Platforms. For the TypeScript/Node.js and C# sample apps on GitHub, the redirect URLs will be similar to this: - Redirect URLs: https://yourhost/bot-auth/simple-start + Redirect URLs: https://\/bot-auth/simple-start No logout URL is required. - `yourhost` is replaced by your actual host. This might be a dedicated hosting site, Glitch or an ngrok redirect to localhost on your development machine. You may not have this information yet if you have not completed or hosted your app (or the sample app mentioned above), but you can always return to this page when that information is known. + Replace `` with your actual host. This might be a dedicated hosting site such as Azure, Glitch, or an ngrok tunnel to localhost on your development machine such as `abcd1234.ngrok.io`. You may not have this information yet if you have not completed or hosted your app (or the sample app mentioned above), but you can always return to this page when that information is known. ## Other authentication providers * **LinkedIn** Follow the instructions in [Configuring your LinkedIn application](https://developer.linkedin.com/docs/oauth2) -* **Google** Obtain OAuth2 client credentials from the [Google API Console](https://console.developers.google.com/) \ No newline at end of file +* **Google** Obtain OAuth2 client credentials from the [Google API Console](https://console.developers.google.com/) diff --git a/msteams-platform/concepts/authentication/auth-flow-bot.md b/msteams-platform/concepts/authentication/auth-flow-bot.md index 608353ba265..502c66d5400 100644 --- a/msteams-platform/concepts/authentication/auth-flow-bot.md +++ b/msteams-platform/concepts/authentication/auth-flow-bot.md @@ -2,7 +2,7 @@ title: Authentication flow for bots description: Describes authentication flow in bots keywords: teams authentication flow bots -ms.date: 02/28/2018 +ms.date: 03/01/2018 --- # Microsoft Teams authentication flow for bots @@ -23,12 +23,14 @@ for an example that demonstrates authentication flow for bots using Node using t 5. The start page redirects the user to the identity provider's `authorize` endpoint. ([View code](https://github.com/OfficeDev/microsoft-teams-sample-auth-node/blob/469952a26d618dbf884a3be53c7d921cc580b1e2/public/html/auth-start.html#L51-L56)) 6. On the provider's site, the user signs in and grants access to the bot. 7. The provider takes the user to the bot's OAuth redirect page, with an authorization code. -8. The bot redeems the authorization code for an access token, and **provisionally** associates the token with the user that initiated the sign-in flow. +8. The bot redeems the authorization code for an access token, and **provisionally** associates the token with the user that initiated the sign-in flow. Below, we call this a *provisional token*. * In the example, the bot associates the value of the `state` parameter with the id of the user that initiated the sign-in process so it can later match it with the `state` value returned by the identity provider. ([View code](https://github.com/OfficeDev/microsoft-teams-sample-auth-node/blob/469952a26d618dbf884a3be53c7d921cc580b1e2/src/AuthBot.ts#L70-L99)) - * **IMPORTANT**: The bot stores the token it receives from the identity provider and associates it with a specific user, but it is marked as "pending validation". The token is not used while in this state. If the `state` pamrameter is valid, Teams then uses a [two-step authentication](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) process to ensure that the user who authorized the bot with the identity provider is the same user who is chatting with the bot. This guards against [man-in-the-middle](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) and [phishing](https://en.wikipedia.org/wiki/Phishing) attacks. On the desktop and web versions of Teams, the verification code is generated and verified automatically; on mobile devices the user may have to enter it manually [as described below](#Mobile-clients). ([View code](https://github.com/OfficeDev/microsoft-teams-sample-auth-node/blob/469952a26d618dbf884a3be53c7d921cc580b1e2/src/AuthBot.ts#L100-L113)) + * **IMPORTANT**: The bot stores the token it receives from the identity provider and associates it with a specific user, but it is marked as "pending validation". The provisional token cannot be used yet: it must be further validated: + 1. **Validate what's received from the identity provider.** The value of the `state` parameter must be confirmed against what was saved earlier. + 1. **Validate what's received from Teams.** A [two-step authentication](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) validation is performed to ensure that the user who authorized the bot with the identity provider is the same user who is chatting with the bot. This guards against [man-in-the-middle](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) and [phishing](https://en.wikipedia.org/wiki/Phishing) attacks. The bot generates a verification code and stores it, associated with the user. On the desktop and web versions of Teams, the verification code is sent automatically by Teams as described below in steps 9 and 10; on mobile devices the user may have to enter it manually [as described below](#Mobile-clients). ([View code](https://github.com/OfficeDev/microsoft-teams-sample-auth-node/blob/469952a26d618dbf884a3be53c7d921cc580b1e2/src/AuthBot.ts#L100-L113)) 9. The OAuth callback renders a page that calls `notifySuccess("")`. ([View code](https://github.com/OfficeDev/microsoft-teams-sample-auth-node/blob/master/src/views/oauth-callback-success.hbs)) -10. Teams closes the popup and sends the string given to `notifySuccess()` back to the bot. The bot receives an invoke message with `name = signin/verifyState`. -11. The bot checks the incoming verification code against the code stored in the user's provisional token. ([View code](https://github.com/OfficeDev/microsoft-teams-sample-auth-node/blob/469952a26d618dbf884a3be53c7d921cc580b1e2/src/dialogs/BaseIdentityDialog.ts#L127-L140)) +10. Teams closes the popup and sends the `` sent to `notifySuccess()` back to the bot. The bot receives an [invoke](https://docs.microsoft.com/en-us/bot-framework/dotnet/bot-builder-dotnet-activities#invoke) message with `name = signin/verifyState`. +11. The bot checks the incoming verification code against the verification code stored with the user's provisional token. ([View code](https://github.com/OfficeDev/microsoft-teams-sample-auth-node/blob/469952a26d618dbf884a3be53c7d921cc580b1e2/src/dialogs/BaseIdentityDialog.ts#L127-L140)) 12. If they match, the bot marks the token as validated and ready for use. Otherwise, the auth flow fails, and the bot deletes the provisional token. ## Mobile clients @@ -44,7 +46,7 @@ When the OAuth callback runs in a mobile browser, the call to `notifySuccess()` If you want to limit signing in to web and desktop only, you can choose to omit the `fallbackUrl` parameter, or point it to your own error page that asks the user to sign in on web or desktop. -Once the Microsoft Teams mobile clients support the complete signin action protocol, including passing the verification code via `notifySuccess()`, they will launch the auth start page in a popup window and ignore `fallbackUrl`. +Once the Microsoft Teams mobile clients support the complete signin action protocol, including passing the verification code via `notifySuccess()`, they will launch the auth start page in a popup window and ignore `fallbackUrl`, just like the desktop and web clients. ## Samples diff --git a/msteams-platform/concepts/authentication/auth-flow-tab.md b/msteams-platform/concepts/authentication/auth-flow-tab.md index 9b92c6e7941..183631ce49f 100644 --- a/msteams-platform/concepts/authentication/auth-flow-tab.md +++ b/msteams-platform/concepts/authentication/auth-flow-tab.md @@ -18,10 +18,10 @@ for an example that demonstrates authentication flow for tabs and bots using Nod 3. The tab then calls the `microsoftTeams.authentication.authenticate()` method and registers the `successCallback` and `failureCallback` functions. 4. Teams opens the start page in an iframe in a pop-up window. The start page generates random `state` data, saves it for future validation, and redirects to the identity provider's `/authorize` endpoint such as https://login.microsoftonline.com/common/oauth2/authorize for AAD. * Like other application auth flows in Teams, the start page must be on a domain that's in its `validDomains` list, and on the same domain as the post-login redirect page. - * **IMPORTANT**: The OAuth 2.0 implicit grant flow calls for a `state` parameter in the authentication request which contains unique session data to prevent a [cross-site request forgery attack](https://en.wikipedia.org/wiki/Cross-site_request_forgery). The examples below use a randomly-generated GUID for the `state` parameter. + * **IMPORTANT**: The OAuth 2.0 implicit grant flow calls for a `state` parameter in the authentication request which contains unique session data to prevent a [cross-site request forgery attack](https://en.wikipedia.org/wiki/Cross-site_request_forgery). The examples below use a randomly-generated GUID for the `state` data. 5. On the provider's site, the user signs in and grants access to the tab. 6. The provider takes the user to the tab's OAuth redirect page with an access token. -7. The tab checks that the returned `state` parameter matches what was saved earlier, and calls `microsoftTeams.authentication.notifySuccess()`, which in turn calls the `successCallback` function registered in step 3. +7. The tab checks that the returned `state` value matches what was saved earlier, and calls `microsoftTeams.authentication.notifySuccess()`, which in turn calls the `successCallback` function registered in step 3. 8. Teams closes the pop-up window. 9. The tab either displays configuration UI or refreshes or reloads the tabs content, depending on where the user started from. diff --git a/msteams-platform/concepts/authentication/auth-silent-AAD.md b/msteams-platform/concepts/authentication/auth-silent-AAD.md index 541aa053b9b..23269f7b1d9 100644 --- a/msteams-platform/concepts/authentication/auth-silent-AAD.md +++ b/msteams-platform/concepts/authentication/auth-silent-AAD.md @@ -6,12 +6,15 @@ ms.date: 02/28/2018 --- # Silent authentication -Silent authentication in Azure Active Directory (AAD) is a simplified form of single sign-on (SSO). It's purpose it to minimize the number of times a user needs to enter login credentials while using your app. +Silent authentication in Azure Active Directory (AAD) is a simplified form of single sign-on (SSO). Its purpose it to minimize the number of times a user needs to enter login credentials while using your app. -If you want to keep your code completely client-side, you can use the [Azure Active Directory Authentication Library](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-libraries) for JavaScript to attempt to acquire an Azure AD access token silently. This means that the user may never see a popup dialog. +If you want to keep your code completely client-side, you can use the [Azure Active Directory Authentication Library](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-libraries) for JavaScript to attempt to acquire an Azure AD access token silently. This means that the user may never see a popup dialog if they have signed in recently. Even though the ADAL.js library is optimized for AngularJS applications, it also works with pure JavaScript single-page applications. +> [!NOTE] +> Currently, silent authentication only works for tabs. It does not yet work when signing in from a bot. + ## How silent authentication works The ADAL.js library creates a hidden iframe for OAuth implicit grant flow, but it specifies `prompt=none` so that AAD never shows the login page. If user interaction is required because the user needs to log in or grant access to the application, Azure AD will immediately return an error that ADAL.js then reports to your app. At this point your app can show a login button if needed. diff --git a/msteams-platform/concepts/authentication/auth-tab-AAD.md b/msteams-platform/concepts/authentication/auth-tab-AAD.md index c9efe23946a..3f8792a4dfe 100644 --- a/msteams-platform/concepts/authentication/auth-tab-AAD.md +++ b/msteams-platform/concepts/authentication/auth-tab-AAD.md @@ -2,7 +2,7 @@ title: Authentication for tabs using Azure Active Directory description: Describes authentication in Teams and how to use it in tabs keywords: teams authentication tabs AAD -ms.date: 02/27/2018 +ms.date: 03/01/2018 --- # Authenticate a user in a Microsoft Teams tab @@ -12,21 +12,21 @@ OAuth is an open standard for authentication used by AAD and many other service The code in this article comes from the Teams sample app [Microsoft Teams tab authentication sample (Node)](https://github.com/OfficeDev/microsoft-teams-sample-complete-node). It contains a static tab that requests an access token for Microsoft Graph and shows the current user's basic profile information from Azure AD. -For a general overview of authentication flow for tabs see the topic [Authentication flow in bots](~/concepts/authentication/auth-flow-tab). +For a general overview of authentication flow for tabs see the topic [Authentication flow in tabs](~/concepts/authentication/auth-flow-tab). Authentication flow in tabs differs slightly from authentication flow in bots. -## Configure an authentication provider +## Configuring identity providers -See the topic [Configure an authentication provider](~/concepts/authentication/configure-AAD) for detailed steps on configuring Azure Active Directory for authentication. +See the topic [Configure identity providers](~/concepts/authentication/configure-AAD) for detailed steps on configuring OAuth 2.0 callback redirect URL(s) when using Azure Active Directory as an identity provider. ## Initiate authentication flow -Usually authentication flow is triggered by a user action. You should not drive the authentication pop-up automatically because this is likely to trigger the browser's pop-up blocker as well as confuse the user. +Authentication flow should be triggered by a user action. You should not open the authentication pop-up automatically because this is likely to trigger the browser's pop-up blocker as well as confuse the user. Add a button to your configuration or content page to enable the user to sign in when needed. This can be done in the tab [configuration](~/concepts/tabs/tabs-configuration) page or any [content](~/concepts/tabs/tabs-content) page. -AAD, like most identity providers, does not allow their content to be placed in an iframe. This means that you will need to add a pop-up page to host the identity provider. In the following example this page is `/tab-auth/simple-start`. Use the `microsoftTeams.authenticate()` function of the Microsoft Teams client SDK to launch this page when your button is selected. +AAD, like most identity providers, does not allow its content to be placed in an iframe. This means that you will need to add a pop-up page to host the identity provider. In the following example this page is `/tab-auth/simple-start`. Use the `microsoftTeams.authenticate()` function of the Microsoft Teams client SDK to launch this page when your button is selected. ```js microsoftTeams.authentication.authenticate({ @@ -44,16 +44,15 @@ microsoftTeams.authentication.authenticate({ ### Notes -* The URL you pass to `microsoftTeams.authentication.authenticate()` is the start page of the authentication flow. In this example that is `/tab-auth/simple-start`. This should match what you registered in the previous step in AAD's Application Registration Portal. +* The URL you pass to `microsoftTeams.authentication.authenticate()` is the start page of the authentication flow. In this example that is `/tab-auth/simple-start`. This should match what you registered in the [AAD Application Registration Portal](https://apps.dev.microsoft.com). -* Authentication flow must start on a page that's on your domain. This domain should also be listed in the [`validDomains`](~/resources/schema/manifest-schema#validdomains) section of the manifest. Failure to do so might result in an empty pop-up. +* Authentication flow must start on a page that's on your domain. This domain should also be listed in the [`validDomains`](~/resources/schema/manifest-schema#validdomains) section of the manifest. Failure to do so will result in an empty pop-up. -* Failing to use `microsoftTeams.authentication.authenticate` might result in problems with the popup not closing at the end of the sign in process. +* Failing to use `microsoftTeams.authentication.authenticate()` will cause a problem with the popup not closing at the end of the sign in process. ## Navigate to the authorization page from your popup page -When your popup page (`/tab-auth/simple-start`) is displayed the following code is run. -The main goal of this page is to redirect to your identity provider so the user can sign in. This redirection could be done on the server side using HTTP 302, but in this case it is done on the client side using with a call to `window.location.assign()`. This also allows `microsoftTeams.getContext` to be used to retrieve hinting information which can be passed to AAD. +When your popup page (`/tab-auth/simple-start`) is displayed the following code is run. The main goal of this page is to redirect to your identity provider so the user can sign in. This redirection could be done on the server side using HTTP 302, but in this case it is done on the client side using with a call to `window.location.assign()`. This also allows `microsoftTeams.getContext()` to be used to retrieve hinting information which can be passed to AAD. ```js microsoftTeams.getContext(function (context) { @@ -86,7 +85,6 @@ After the user completes authorization, the user is redirected to the callback p * See [get user context information](~/concepts/tabs/tabs-context) for help building authentication requests and URLs. For example, you can use the user's name (upn) as the `login_hint` value for Azure AD sign-in, which means the user might need to type less. Remember that you should not use this context directly as proof of identity since an attacker could load your page in a malicious browser and provide it with any information they want. * Although the tab context provides useful information regarding the user, don't use this information to authenticate the user whether you get it as URL parameters to your tab content URL or by calling the `microsoftTeams.getContext()` function in the Microsoft Teams client SDK. A malicious actor could invoke your tab content URL with its own parameters, and a web page impersonating Microsoft Teams could load your tab content URL in an iframe and return its own data to the `getContext()` function. You should treat the identity-related information in the tab context simply as hints and validate them before use. * The `state` parameter is used to confirm that the service calling the callback URI is the service you called. If the `state` parameter in the callback does not match the parameter you sent during the call the return call is not verified and should be terminated. - * The `microsoftTeams.navigateCrossDomain()` function is not available in the context of the identity provider's popup. As a result, it is not necessary to include the identity provider's domain in the `validDomains` list in the app's manifest.json file. ## The callback page @@ -140,11 +138,11 @@ Your app can set its own session cookie so that the user need not sign in again For more information on Single Sign-On (SSO) see the article [Silent authentication](~/concepts/authentication/auth-silent-AAD). -For more information on using AAD authentication outside of a web context (in bots or in mobile) see [Authentication for bots (AAD)](~/concepts/authentication/auth-bot-AAD) +For more information on using AAD authentication for bots, see [Authentication for bots (AAD)](~/concepts/authentication/auth-bot-AAD) ## Samples For sample code showing the tab authentication process using AAD see: * [Microsoft Teams tab authentication sample (Node)](https://github.com/OfficeDev/microsoft-teams-sample-complete-node) -* [Microsoft Teams tab authentication sample (C#)](https://github.com/OfficeDev/microsoft-teams-sample-complete-csharp) \ No newline at end of file +* [Microsoft Teams tab authentication sample (C#)](https://github.com/OfficeDev/microsoft-teams-sample-complete-csharp) diff --git a/msteams-platform/concepts/authentication/authentication.md b/msteams-platform/concepts/authentication/authentication.md index eb28fd074d9..869bd8ec9d4 100644 --- a/msteams-platform/concepts/authentication/authentication.md +++ b/msteams-platform/concepts/authentication/authentication.md @@ -11,13 +11,13 @@ In order for your app to access user information stored in Azure Active Director General information on authentication flow as it applies to any authentication provider: * [Authentication flow in tabs](~/concepts/authentication/auth-flow-tab) describes how tab authentication works in Teams. This shows a typical web based authentication flow used for tabs. -* [Authentication flow in bots](~/concepts/authentication/auth-flow-bot) describes how authentication works within a bot in your app in Teams. This shows a non-web based authentication flow useful for bots or for mobile. +* [Authentication flow in bots](~/concepts/authentication/auth-flow-bot) describes how authentication works within a bot in your app in Teams. This shows a non-web based authentication flow used for bots on all versions of Teams (web, desktop app, and mobile apps) Detailed implementation walkthroughs for authentication using Azure Active Directory: * [AAD authentication in tabs](~/concepts/authentication/auth-tab-AAD) describes how to connect to Azure Active Directory from within a tab in your app in Teams. -* [AAD authentication in bots](~/concepts/authentication/auth-bot-AAD) describes how to connect to Azure Active Directory from within a tab in your app in Teams. -* [Silent authentication (AAD)](~/concepts/authentication/auth-silent-AAD) describes how to implement single sign on in your app using Azure Active Directory. +* [AAD authentication in bots](~/concepts/authentication/auth-bot-AAD) describes how to connect to Azure Active Directory from within a bot in your app in Teams. +* [Silent authentication (AAD)](~/concepts/authentication/auth-silent-AAD) describes how to implement single sign on (SSO) in your app using Azure Active Directory. Currently SSO only works for tabs. Sample code showing bot authentication in Node: