1
votes

I deployed a Cortana bot written in Node.js on my Azure account. The bot uses the Cortana channel with "Connected Services" turned on (so I can login in the bot using an account from my Azure Active Directory). The login works fine.

My problem is that now I don't know how to get info about the logged-in user (e.g. email address) in my bot.

I'm guessing I would need to get some token from the session data and then send an API request asking Azure for the user's data?

There is this botauth example for Node.js but the instructions for running it are outdated.

1
about the node.js example, can you clarify what is outdated in the example?Andre Teixeira
You got this working with Azure AD? Nice. I can't seem to figure out the right things to fill into the right boxes of the Connected Service screen - any chance you could post a blured screenshot or something like that with what settings from the Azure AD app registration went where in the Cortana Connected Service screen?Jonathan Rupp

1 Answers

0
votes

while I don't have a sample on how to do this with Node, maybe the solution in C# would help?

The way you do this is to inspect the entities collection coming in off the Activity object to the controller. Since this is part of every request to the bot, you can do this at any time.

Inside the entities collection, Cortana puts an authorization entry containing the token that resulted from the authentication flow of the Connected Service. If you're using the Connected Service to hit a Microsoft service (aka logging in to Live, MSA, etc), you can turn this token around and request information from the Microsoft Graph about the user.

In C#, it looks like this:

// auth token from cortana's connected service stored as Entity object of type 'authorization' with child property 'token' holding the actual value
var token = activity.Entities.Single(e => e.Type == @"authorization").Properties.Value<string>(@"token");
using (var client = new HttpClient())
{
    // The token can be used to query the Graph, but only because we know that it is from MS Identity. We couldn't query the Graph like this if we were using our own Identity provider (eg: Contoso Identity)
    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(@"Bearer", token);
    try
    {
        var response = await client.GetAsync(@"https://graph.microsoft.com/v1.0/me").ConfigureAwait(false);
        if (response.IsSuccessStatusCode)
        {
            var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

            /* Response from /me looks like:
                {
                    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
                    "givenName": "Brandon",
                    "surname": "H",
                    "displayName": "Brandon H",
                    "id": "<unique user id!>",
                    "userPrincipalName": "<E-MAIL ADDRESS!!>",
                    "businessPhones": [],
                    "jobTitle": null,
                    "mail": null,
                    "mobilePhone": null,
                    "officeLocation": null,
                    "preferredLanguage": null
                }
            */
        }
    }
    catch { }
}

hope that helps! If you want to play with what you get back from various tenants of the graph, the Graph Explorer is a great way to do this.