Episode #132 – Creating Microsoft Teams Tabs with Single Sign-On support using Yo Teams

Here you can find the transcript of Episode #132 of PiaSys TechBites.

Welcome back to PiaSys Tech Bites. Today I want to talk with you about how we can create Teams Tabs and Teams Task Modules with the Yeoman Generator for Teams, including the Single Sign-On capability. First of all, let me explain you why we need Single Sign-On. If you think about that, very often when users consume customizations in Microsoft Teams, whether they use the web client, the desktop client, or the mobile clients, it is really powerful being able to access content and services provided by the Microsoft 365 ecosystem. In order to do that, we need an access token, and using the Single Sign-on capability of Microsoft Teams, we can quite easily get an access token in order to access those contents and services in the name of the currently connected user.

From a technical point of view, there are some limitations in the Single Sign-on for Microsoft Teams. And specifically, one of the limitations is that we get by default a really restricted set of permissions, and in order to do anything more than what is provided by the out-of-the-box capabilities, we need to provide the access token that we get to a backend API, which we’ll use the On-Behalf flow of open authorization in order to get an access token to consume a backend API.

So for example, if you want to access a mailbox, or if you want to access SharePoint Online, or any other workload of Microsoft 365, you will have to do the Single Sign-On in the client based solution running in Teams. And then you will have to provide the access token to a backend API, where using the On-Behalf flow, you would be able to get a new access token to access the actual workload that you want, or that you need to access in the backend.

Moreover, when you do that, you need to register an application in Azure Active Directory, and the very first time a user will use the application, he or she will have to consent the application. In order to avoid that, it is better to give a tenant admin consent at the very beginning, so that the end-users will not have to provide their own personal consent. Last but not least, the Single Sign-On functionality nowadays targets Azure Active Directory only. So if you want to use any other platform or any other service, you will still have to create a popup dialog to get the credentials of the user in order to access a target service, which is not secured under Azure Active Directory.

So let me move to the demo environment, and let me show you how to do that in practice. So first of all, let’s have a look at a Team tab with support for Single Sign-On in action. Here is my tab, and as you can see here, I can get a greeting message: “Hello, Paolo Pialorsi”, where the name has been retrieved through the access token that I’ve got from Azure Active Directory using the Single Sign-On capability. So I can see what the user is and what the context of the user is from a security point of view. How can we do that? Well, first of all, we need to scaffold the solution using the Yo Teams generator. So let’s do that. Yo Teams. And I’m going to do that in a dedicated folder. So I will provide a bunch of answers to the questions of the Yo Teams generator. So here is solution name, I will use the current folder, this will be the project name and company, the version of the manifest, any partner ID, if any, or I can skip it.

I will create a tab, which is totally okay. And this will be for example, the URL of my solution. I want to show a loading indicator. I don’t care about all of these questions about the header, the test framework, application insight, and stuff like that. And then I will provide a name. Yo Teams SSO Sample. Then it will be, for example, a configurable tab running in a Team. And now here is the very important question. Do you require Azure AD Single Sign-On support for the tab? And if you reply yes, which is the default answer, you will have to provide the ID of an application that you will have to register in Azure Active Directory. Which is something that I already did for my sample solution, and let me show you what I did. Here is my application registered in Azure ID. As you can see, it is a regular application, and under the expose an API, I configured my application to expose an API with a permission scope called access_as_user.

I provided a unique URI for my application, and I also configured as the authorized client applications to avoid the prompt for the consent when these applications will consume my API for these two global unique identifiers, which identify two different application registered in my Azure ID tenant. And those applications are the Teams mobile or desktop application, as well as the Teams web application, which is the first one. There is a document in docs.microsoft.com that you can see in the references just below this video, where you can see and you can read all of the steps needed to do this registration. Then in the API permissions section, I configure the delegated permissions to access email, offline_access, open_ID, profile, and User.Read. These are the permissions that we can get through Single Sign-On and Azure Active Directory whenever we run a solution, a custom solution, in Teams. And that’s why I configured those permissions. Notice that all of them are delegated permissions. So we get a Single Sign-On experience indeed with the delegated access token for the currently connected users.

Once you have that data, you can simply copy the ID of the application that you registered, and you can paste it in the UI of the Yo Teams generator. Then you will provide the URI of your solution. So you will have to copy the application ID URI from the Expose an API. Let’s say that I want to use this one. And then you will have to provide many more answers to the questions of the Yeoman generator, but from a Single Sign-On point of view, you are done and you will simply have to wait for the scaffolding. Which I already did indeed in another solution that I’m going to show you. And here I have a tab which I created with Yo Teams generator, as like as I was going to do before using the Yeoman generator in my console window.

And here we have a tab. And in the tab, the scaffolded solution will have a ComponentWillMount method which will initialize the tab and do the magic for us about the Single Sign-On part of the story. In fact, in the ComponentWillMount we have, in the microsoftTeams.initialize method, we have a call to the getAuthToken method of the Microsoft Teams authentication which is available through the SDK of Microsoft Teams. And in there, this method will retrieve the access token from the Azure Active Directory and, if it will be successful, it will provide the token to our logic. And if not, we will be able to track and to manage any failure. So when we get the token, we can eventually decode the token using a JWT decoder, and we will be able to see the information inside the token like, for example, user name, the user email address, and stuff like that.

Or we can just provide this token, as I told you, to a backend API, which using the On-Behalf flow, will be able to do the actual retrieval of an access token to consume a backend workload of Microsoft 365 through Azure Active Directory and Microsoft Graph. When we get the name, we set it in the state of the current tab because in the render method of the tab, we simply show the “Hello” message for the currently connected user. As you can see here, this.state.name. Moreover, in the manifest of the application, you will have to register this webApplicationInfo section, which the Yo Teams generator creates for you, and in which you will have to provide the ID of the app that you registered in Azure Active Directory, as well as the unique URI of your application. These two information come out from the environment file that the Yo Team generator will create and configure for you.

And in fact, here you can see the application ID of the application that I already configured, as well as the unique URI for my application. Once you have done that data, you can run a gulp ngrok-serve, or you can publish the solution on the Cloud, up to you, and then you can leverage this capability in your Teams tab. Just to give you an idea of what is happening under the cover, let me go back to the Teams tab. Let me press F12 and go to the sources, and let me start again, refresh this page to make another request for the access token. As you will see, I have a breakpoint right here, and we can see that we get the token inside the JavaScript code. Let me copy the value of the token and let me use the JWT or jot.ms to show you the content of the token.

So let me paste it. I have to remove the quotes at the end and at the beginning. And as you can see in this access token, we see that we have, as an audience, the application that we are targeting. Moreover, we can see that the user is the one who is authenticated right now. And we can see that the permission scope is access_as_user, which is the one that we configured as the scope provided by the custom application that we registered in Azure Active Directory.

And then we simply decode the value, get the username, as you can see in the decoded one, we have all of the information that we were able to see also using the jwt.ms tool. So let me run it again. Of course, we run in time out so I need to retry this request, but it doesn’t really matter. And once I’ve done that, we will be able to see that we have our information in the UI of the Teams tab. And here we are. So have fun with Single Sign-On and in the future, I will show you how to do the backend part of the story using the On-Behalf flow. Like always, thank you for watching this video, I hope you found it interesting, and I’m really looking forward to seeing you next week. And remember, subscribe to this channel. Thank you.