Contents tagged with Microsoft Teams

  • Using Device Codes to authenticate Bots with Azure AD

    Tags: Bot Framework, Microsoft Teams, npm, Microsoft Azure, Microsoft Graph, Azure AD

    I’ve been building chat-bots for a while now and I’m seeing more and more requests of building these bots for enterprises. For bots targeted at the enterprise, perhaps being hosted in Microsoft Teams, one of the first requirements is that they should get data from their internal systems and most specifically from Office 365, through the Microsoft Graph. The problem here is that we need to authenticate and authorize the user, through Microsoft Azure AD, to be able to access these resources. A Microsoft Bot Framework bot, does not inherit the credentials or security tickets from the application the bot is being invoked from, so we need handle this ourselves. For instance, even though you have logged in to Microsoft Teams, or Skype for Business or your Intranet – your security token cannot (and should not) be passed to the Bot.

    This is not mission impossible, and there are multiple ways of implementing this. For instance if you’re building Bot Framework bots using .NET you can use the AuthBot and with node.js there’s the botauth module. There’s also other (a bit weird and specialized) ways of doing this by using the backchannel.

    All of these are custom implementations with either sending an already existing access token to the bot or using home brewed magic number generators. But, there’s a much simpler way of doing this – using the native and built-in features of the Azure Active Directory Authentication Library (ADAL), specifically using the OAuth 2.0 Device Flow.

    In this post I will demonstrate how to create a bot from scratch and use the device flow to sign in and get data from Microsoft Graph. It will all be built using node.js and TypeScript – but the procedure is the same for any kind of environment.

    Creating the bot

    First of all we need to create a bot using the Bot Framework portal. Give the bot a name, handle, description and specify the messaging endpoint. You can use localhost for testing but in the end you should have a publically available URL to be able to use it in the different Bot channels. In this sample we need to make sure that the messaging endpoint ends with /api/messages. Then you need to create a Microsoft App ID and a password – just follow the wizard and copy and take a note of the ID and specifically the password – you will only see it once. Once you’re done, save your bot.

    Configuring the App platform for the bot

    The bot created in the Bot Framework portal, is essentially an Application in the Microsoft Application Registration Portal. In order to use this Application ID with Azure AD and Microsoft Graph, we need to log in to that portal and find our newly registered bot and then add a platform for it. In this case let’s add a Native Application. You don’t have to configure it or anything, it just needs to have a platform.

    Setting the platform for the App

    In this portal you can also add the delegated permissions for your bot, under Microsoft Graph Permissions. For the purpose of this demo we only need the User.Read permissions.

    Let’s write some code

    Next step is to actually start writing some code. This will be done in node.js, using TypeScript and a set of node modules. The most important node modules used in this demo are:

    • webpack – bundles our TypeScript files
    • ts-loader – webpack plugin that transpiles TypeScript to JavaScript
    • express – node.js webserver for hosting our Bot end-point
    • adal-node – ADAL node.js implementation
    • @microsoft/microsoft-graph-client – a Microsoft Graph client
    • botbuilder – Bot Framework bot implementation

    All code in this sample are found in this Github repo: https://github.com/wictorwilen/device-code-bot. To use it, just clone the repo, run npm install. Then to be able to run it locally or debug it you can add a file called .env and in that file add your Application ID and password as follows:

    MICROSOFT_APP_ID=fa781336-3114-4aa2-932e-44fec5922cbd
    MICROSOFT_APP_PASSWORD=SDA6asds7aasdSDd7

    The hosting of the bot, using express, is defined in the /src/server.ts file. For this demo this file contains nothing specific, part from starting the implementation of the bot – which is defined in /src/devicecodebot.ts.

    In the bot implementation you will find a constructor for the bot that creates two dialogs; the default dialog and a dialog for sign-ins. It will also initialize the ADAL cache.

    constructor(connector: builder.ChatConnector) {
        this.Connector = connector;
        this.cache = new adal.MemoryCache()
    
        this.universalBot = new builder.UniversalBot(this.Connector);
        this.universalBot.dialog('/', this.defaultDialog);
        this.universalBot.dialog('/signin', this.signInDialog)
    }

    The implementation of the default dialog is very simple. It will just check if we have already logged in, but in this demo we will not set that value, so a login flow will always be started by starting the sign-in dialog.

    The sign-in dialog will create a new ADAL AuthenticationContext and then use that context to acquire a user code.

    var context = new AuthenticationContext('https://login.microsoftonline.com/common', 
      null, this.cache);
        context.acquireUserCode('https://graph.microsoft.com', 
          process.env.MICROSOFT_APP_ID, '', 
          (err: any, response: adal.IUserCodeResponse) => {
            ...
    });

    The result from this operation (IUserCodeResponse) is an object with a set of values, where we in this case should pay attention to:

    • userCode – the code to be used by the user for authentication
    • message – a friendly message containing the verification url and the user code
    • verificationUrl – the url where the end user should use the user code (always aka.ms/devicelogin)

    We use this information to construct a Bot Builder Sign-In Card. And send it back to the user:

    var dialog = new builder.SigninCard(session);
    dialog.text(response.message);
    dialog.button('Click here', response.verificationUrl);
    var msg = new builder.Message();
    msg.addAttachment(dialog);
    session.send(msg);

    This allows us to from Bot Framework channel invoke the authorization flow for the bot. The end-user should click on the button, which opens a web browser (to aka.ms/devicelogin) and that page will ask for the user code. After the user entered the user code, the user will be asked to authenticate and if it is the first time also consent to the permissions asked for by the bot.

    In our code we then need to wait for this authorization, authentication and consent to happen. That is done as follows:

    context.acquireTokenWithDeviceCode('https://graph.microsoft.com',
       
    process.env.MICROSOFT_APP_ID, response, 
      (err: any, tokenResponse: adal.IDeviceCodeTokenResponse) => {
        if (err) {
          session.send(DeviceCodeBot.createErrorMessage(err));
          session.beginDialog('/signin')
        } else {
            session.userData.accessToken = tokenResponse.accessToken;
            session.send(`Hello ${tokenResponse.givenName} ${tokenResponse.familyName}`);
            ...
        }
    });	

    The result from this operation can of course fail and we need to handle that, in this case just sending the error as a message and restart the sign-in flow. If successful we will get all the data we need to continue (IDeviceCodeTokenResponse) such as access-token, refresh-token, user-id, etc. In a real world scenario you should of course store the refresh token, in case the access token times out. And it is also here that we potentially tells our bot that the user is signed in redirects subsequent dialogs to what we want to do.

    Now we can use this access token to grab some stuff from the Microsoft Graph. The following code, with a very simplistic approach, where wo do not handle timed out access tokens, we just grab the title of the user and sends it back to the user.

    const graphClient = MicrosoftGraph.Client.init({
        authProvider: (done: any) => {
            done(null, session.userData.accessToken);
        }
    });
    graphClient.
        api('/me/jobTitle').
        version('beta').
        get((err: any, res: any) => {
            if (err) {
                session.send(DeviceCodeBot.createErrorMessage(err));
            } else {
                session.endDialog(`Oh, so you're a ${res.value}`);
            }
        });
        }
    });

    Run the application

    To run the application first we need to transpile and bundle it using webpack like this:

    npm run-script build

    The we start the express server like this:

    npm run-script run

    To test it locally we need to use the Bot Framework emulator. Download it, run it and configure it to run at http://localhost:3007/api/messages. Type anything in the emulator to start the sign-in experience

    Testing the bot with the Bot Framework emulator

    As soon as you’ve written something the Sign-In card will be displayed. When you click on the button a browser window will open and you will be asked to type the code. When you’ve done that you will be asked to sign-in and consent. And shortly after that the bot will come alive again and type the users name and if all works well, also the job title of the user.

    Consenting the device code bot

    If you decide to publish your bot (for instance to Azure, all the necessary files are in the Github repo to Git publish it to Azure) you can also use the bot in other channels, for instance Skype:

    The device code bot in Skype

    Summary

    As you’ve now seen. It is very easy to create a simple and elegant sign-in flow for your bots, without sacrificing any security, and all using standard features of ADAL and OAuth. This will nicely work with any Azure AD accounts, with MFA or not.

  • yo teams have a new home, and officially backed by Microsoft

    Tags: Microsoft Teams, Yeoman, Npm, Git

    A couple of months back I started creating a Yeoman generator to make it easier for me to scaffold, build and deploy the Microsoft Teams extensions (now apps). I’ve received very good feedback on it and had some very nice contributions to the project, which was hosted on my public Github account.

    To really make this available for everyone to use I’ve been discussing this project with the Microsoft Teams team about having it “officially backed” by the real team and nut just me as an individual. After some interesting discussions the Microsoft Teams generator now have a new home.

    The Microsoft Teams Yeoman generator are now transferred to the OfficeDev organization on Github and lives in this repository: https://github.com/OfficeDev/generator-teams

    I think this is great and it will allow more organizations to actually use the generator. We’ve switched to MIT licensing and we added some contribution guidelines to be able to do this move. The rest is intact. All the old links to the repo will now redirect to the new one and you still use npm to install it in the same way.

    We have some nice updates coming shortly to it, of which some you can see in the preview branch, that uses all the latest and greatest features of Microsoft Teams Apps.

    A big thank you to Bill Bliss who set things in motion and did all the heavy lifting, and of course to all the contributors to the generator and to the great Microsoft Teams team!

    #yoteams

  • yo teams: a full Microsoft Teams extensibility Yeoman generator

    Tags: Microsoft Teams, Bot Framework, TypeScript, Yeoman, Office 365, Gulp, Git

    A couple of weeks back I published a Yeoman generator to build Tabs for Microsoft Teams. Since then I've continued to add stuff to it as the Teams team has continued to add features to their extensibility story. So, this generator is not only for creating Tabs, but now also for adding Bots and Custom Bots to Microsoft Teams. With that I decided to rename the generator to yo teams (generator name is generator-teams).

    I'm very thankful to the over 600 downloads within less of a month, and all the positive feedback, the issues and PR created. Keep it coming.

    What's new?

    The two big new features of the generator is the ability to add either a reference to an existing bot that you want to use (your own, or any bot in the Bot Framework directory) or to create a bot from scratch, using the Bot Framework. You can also add a custom bot, which is a Microsoft Teams specific webhook that acts like a bot, which can be used by specific Teams only and you don't have to add it to the Bot Framework - perfect for those internal smart bots you want to build.

    yo teams

    The source code has also gone through some heavy refactoring with sub-generators and all. There's more to come…

    Both the Bot and Custom bot uses the JavaScript/TypeScript implementations of the Bot Framework and you have some boilerplate code to get started, including readme files of the essentials.

    If you have any issues, or feedback, or problem or just feeling chatty, then use the Issues list on Github.

    What do I need to do?

    If you already used the old generator, uninstall it with npm uninstall generator-teams-tab --global and then install the new generator with npm install generator-teams --global. All your current solutions will work, but I recommend you to, if you feel like it, to "move" all your code over to a newly created project.

    The old npm package is deprecated and you will get a warning if you try to install it.

    The Github repository has been renamed, but the old one will still redirect you to the correct location. You can find it here: https://github.com/wictorwilen/generator-teams

  • Congratulations to the Microsoft Teams team on an excellent delivery

    Tags: Microsoft Teams, Office 365

    A big round of applause for Microsoft and the team behind Microsoft Teams for now being general available (GA) worldwide. Today, they lit up the Teams icon in the Office 365 waffle for all tenants (unless your admins are being boring and has turned it off).

    image

    It's been awesome to be a part of this preview journey, which started last summer. Avanade was selected as one of the TAP members, in a preview program shrouded in a secrecy I've not seen at Microsoft before. Our IT department slowly trickled it out, so that we had a chance of learning how Microsoft Teams could fit into our organization and our way of working. A big thanks to David who have mastered the preview program internally.

    When Microsoft Teams was unveiled to the public, back in November, we did our first point-of-view based on our experience so far. Since then I would say that the way we work has changed dramatically. Many of our teams and interest groups has quickly adopted this new chat-based workspace - not just for chatting but as the preferred channel for communication and collaboration. It fits our style of work perfectly, given how spread out our teams are and the different time zones we're working in.

    Personally I've been way more effective in my work since we started to adopt Microsoft Teams. The number of unnecessary e-mails has gone done dramatically, my inbox is not flooded with simple questions, or links, or things that can more easily be expressed through a chat. One thing that has surprised me is how much more we use the ad-hoc chats compared to what I've expected, we don't all have to be online at the same time - you can easily go back and see what's been discussed while you were away or in a meeting. Sharing of files and notes is so much easier now and it allows us to have an ongoing discussion about them.

    It's been a blast discussing Microsoft Teams with my clients. And I'm thrilled that some of them now are leading with "Teams first" - that is you create a Team, not a SharePoint team site, not an Office 365 Group. You get them for free with Teams anyways. This will change the way collaboration is done for enterprises going forward, without doing trade offs for compliance, governance and security.

    This is the first release of many to come. And they number of features that has popped up over the last few months are incredible. And I'm sure we will see some more productivity enhancers going forward.

    Once again, thank you to the team behind Microsoft Teams.

  • yo teams-tab: A Microsoft Teams Tabs Yeoman generator

    Tags: Microsoft Teams, Office 365, Yeoman, Git, Gulp

    I'm happy to announce that today at SharePoint Saturday Munich I presented a new Yeoman generator for building Microsoft Teams Tabs projects. Tabs in Microsoft Teams is a great way to extend the user interface and to do integrations to other systems and provide visualizations. Tabs are based on a JavaScript framework, a set of web pages and a manifest describing the Tab. It requires a set of manual steps to both build out the pages, configuring CSS, hooking up the JavaScripts, deploying it all to a web site hosted in the cloud, writing the manifest, packaging the manifest into a zip file and more.

    With the Teams Tab generator you can in an easy manner scaffold out the project and get a build and deployment pipeline, and be up and running in a few minutes.

    yo teams-tab

    The project that will be created is a TypeScript based project with a set of Gulp tasks to build the project and package the manifest, and optionally a built-in Express server to host the web sites and configuration so that you can with a simple command deploy your project to an Azure Web App.

    How to get it

    The generator is published as an npm package and you use npm to install it. The following command will install it as a global package for you to scaffold your Teams tabs.

    npm install generator-teams-tab --global

    How to use it

    To create a new Teams Tab all you need to do is open up a command prompt and use Yeoman to create the project. The generator will ask you a set of questions and your project will configured based on those.

    yo teams-tab

    How to use the project

    The project contains all source code you need to build and deploy tabs. Use Visual Studio Code or whatever text editor you prefer. The source code is divided into two areas. The first one being the actual tabs (pages and scripts), located in ./src/app You will find one folder called web which contains the web pages required for a tab; such as the actual tab page, the configure page and remove page. In the scripts folder you will have the TypeScripts file in which you build the logic for your tabs. For instance the actual main tab page, tab.html, has a corresponding tab.ts TypeScript file. You'll get it…

    In the ./src/app folder there is also a TypeScript file called server.ts. Note, this file only exists if you answers yes to the question on using Express to host the Tab. This file is the server side node.js web server. If you need to modify the paths or want it to do fancier stuff than just client-side scripting this is where you start hacking.

    There's also a folder calle ./src/manifest which contains the Tab manifest. A json file you might want to configure. And that folder also contains the two images you need to have for a Tab.

    The tab project

    How to build it

    You build the tab by using a simple Gulp task that will transpile and bundle your TypeScript into JavaScript and sets up the web server. Just use the following command to build it

    gulp build

    Once you've built it you can follow the instructions in the README.md file to deploy it to an Azure Web App.

    The manifest for the tab is created by using another Gulp task:

    gulp manifest

    This task will create a zip file that you use to upload to your Teams team and it references the specified web site hosting the tabs. The file being created is located at ./package/tab.zip

    This is great, but I want to…

    I know, you want to have more stuff in the generator. It's all available on Github for you to grab and hopefully come back with suggestions. Go git it here: https://github.com/wictorwilen/generator-teams-tab

    I'm looking forward to feedback and I'll keep updating the generator in line with what the Teams team are doing with their JavaScript framework, which is currently at 0.4.

    glhf

About Wictor...

Wictor Wilén is the Nordic Digital Workplace Lead working at Avanade. Wictor has achieved the Microsoft Certified Architect (MCA) - SharePoint 2010, Microsoft Certified Solutions Master (MCSM) - SharePoint  and Microsoft Certified Master (MCM) - SharePoint 2010 certifications. He has also been awarded Microsoft Most Valuable Professional (MVP) for seven consecutive years.

And a word from our sponsors...