Authentication in Cortana Skills

Play Authentication in Cortana Skills
Sign in to queue


Cortana Skills can make calls to other services that require authentication, such as the Microsoft Graph. The easiest way to implement this for a service that requires OAuth 2.0 authentication is to configure a Connected Service for your skill and let Cortana manage the authentication token which is passed to your skill on invocation. Alternatively, you can manage the authentication entirely within your skills service which requires more work but gives greater flexibility. In this session, we’ll walk through how to configure a Connected Service and how to access the authentication tokens within your skill service to make authenticated calls, and we’ll cover how to implement skill-managed authentication.



Session Type:






The Discussion

  • User profile image

    Sample code shown above for live connect APIs does not work as shown in video. I updated the code to use Microsoft Graph APIs.

    Here is the updated MessageRecievedAsync Method call -

     public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
                var message = await argument;
                var activity = await argument as Activity;
                string authAccessToken = String.Empty;
                string ShowText = String.Empty;
                string SpokenText = String.Empty;
                    foreach (var entity in activity.Entities)
                        if(entity.Type == "AuthorizationToken")
                            dynamic authResult = entity.Properties;
                            authAccessToken = authResult.token;
                if (String.IsNullOrEmpty(authAccessToken))
                    ShowText = "Error: Cortana did not send expected authorization token";
                    SpokenText = "Error invoking the Birthday Tracker. Cortana did not send the expected authorization token";
                    //Use access token to get user info
                    //var url = "" + authAccessToken;
                    //var url = "" + authAccessToken;
                    var url = "";
                    using (var client = new HttpClient())
                        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + authAccessToken);
                        var response = await client.GetAsync(url);
                        if (!response.IsSuccessStatusCode)
                            //Api call failed, present an error to user
                            ShowText = "Failed to connect to profile with response code :" + response.ToString() + " Response phase" + response.ReasonPhrase.ToString() + "auth access token" + authAccessToken + "content" + response.Content.ToString();
                            SpokenText = "Sorry, I couldn\'t connect to your profile";
                            var responseString = await response.Content.ReadAsStringAsync();
                            //Extract usefule info from API response
                            dynamic data = JsonConvert.DeserializeObject(responseString);
                                //Extract useful info from API response
                                var givenName = (string)data.givenName;
                                var surName = (string)data.surname;
                                SpokenText = ShowText = $"Your name, {givenName} {surName}";
                                //var month = (int)data.birth_month;
                                //var day = (int)data.birth_day;
                                //var birthdayDate = new DateTime(DateTime.Today.Year, (int)month, (int)day);
                                //int daysUntilBirthday = (int)(birthdayDate - DateTime.Today).TotalDays;
                                //// Have we already passed the birthday?
                                //if (daysUntilBirthday < 0)
                                //    daysUntilBirthday = (int)(birthdayDate.AddYears(1) - DateTime.Today).TotalDays;
                                //// Format spoken text
                                //// Special responses if birthday is today or tomorrow
                                //SpokenText = ShowText = $"Hi {name}. There are {daysUntilBirthday} days until your birthday.";
                                //if (daysUntilBirthday == 0)
                                //    SpokenText = ShowText = $"Today is your birthday. Happy birthday, {name}";
                                //else if (daysUntilBirthday == 1)
                                //    SpokenText = ShowText = $"Hi {name}. Tomorrow is your birthday.";
                            catch (Exception)
                                // Name or birthday not available in response, present an error
                                ShowText = "Sorry, I couldn\'t get your info. Failed to get name or birthday";
                                SpokenText = "Sorry, I couldn\'t get your info";
                //return our reply to user
                Activity reply = activity.CreateReply(ShowText);
                reply.Speak = SpokenText;
                reply.InputHint = InputHints.IgnoringInput;
                await context.PostAsync(reply);
             //   await context.PostAsync($"{this.count++}: You said {message.Text} And  = {authAccessToken}");
  • User profile image

    how i can get oauth id token from cortana? i want to set openid scope and can get id token from cortana, but i don't fins any api i can use to get it.
    the id token from cortana is very useful to skill service, since most of time skill service need call other service to implement bussiness logic, if we can have id token in skill we can post the id token to other service. id token canbe used to validate the users and app information.

Add Your 2 Cents