Adding Authentication to Your Cortana Skill

Warning

Cortana Skills handle authentication differently than Microsoft Bot Framework.

If your skill uses a service that requires user authentication using OAuth 2.0, then you may use Connected Account feature in Cortana. The Connected Account feature in Cortana is used to get an access token for use with the service. All you must do is provide Cortana a few OAuth 2.0 settings and Cortana manages the rest for you.

You decide whether Cortana signs in the user when they invoke your skill or only when they activate a feature of your skill that requires authentication. Cortana initiates the sign-in process on your identity server. The user is prompted to sign in. If you use the code grant flow and have set a scope of offline_access, then Cortana automatically reauthenticates your user using a refresh token. Your user is reauthenticated until one of the following situations occurs.

  • User disconnects the skill in Cortana Notebook

    Note

    Disconnect the skill in Cortana Notebook to clear the authentication state.

  • Refresh token expires

  • User changes password

Cortana Skills supports the Code Grant flow and Implicit Grant flow for OAuth 2.0. For information about adding a connected account to your skill, visit the Manage user identity in the channel configuration for Cortana section.

The Connected Account feature supports using a single identity service. If your skill requests different services that use different identity services, then you may use Connected Account with one of the services. You may use Connected Account with another service, but you must use a different mechanism to authenticate your user with the service.

Get Your Cached Access Token

If you configure the channel for connected accounts in Cortana, then Cortana sends the authentication token to your skill as entity data. From the point you ask Cortana to authenticate your user, the entities property for each message includes an AuthorizationToken object.

The AuthorizationToken object includes the following properties.

Name Type Description
type string The type of the object. The only acceptable value is AuthorizationToken.
token string The access token. The value is null under the following conditions.
  • User cancels the sign-in process
  • User does not give consent
status string The status of the access token. The following are the possible values.
  • 0 : The token field is set to valid access token.
  • 1 : Sign in succeeded. This value is set on the first message following user sign in. The token field is set to valid access token.
  • 2 : Sign in canceled by user. The token field is set to null.

Example of AuthorizationToken Object

{                             
    "type": "AuthorizationToken",  
    "token": string,
    "status": string                                
}

Create an OAuth Enabled Cortana Skill

Create an OAuth 2.0-enabled Cortana skill using the following steps.
Example: Creates a bot in Azure Bot Service using the Basic C# bot template.

Note

If you have not created a bot and looking for more information on how to get started, then visit the Create a bot with Bot Service page.

  1. Sign into the Microsoft Azure Portal.

  2. In the portal, click the name of your bot.

  3. Under BOT MANAGEMENT, click on the Channels icon.

  4. To create the Cortana channel, click the Cortana icon.

    Cortana channel icon

    Note

    If your bot is already connected to the Cortana channel, then click Edit to access the Default settings.

    Edit Channels

  5. Scroll down the Configure Cortana page, under Cortana should manage my user's identity, click on the toggle.

    Manage user identity through connected services

  6. Fill in the OAuth configuration field values.
    Prompt user to Sign in.

    1. Sign in at invocation | radiobox
      If you select at invocation then Cortana manages the log in when the user first invokes the skill. Otherwise you can send an OAuthCard attachment before a resource call.

    2. Account Name
      The account name for your Cortana Skill.

    3. Client ID The identifier for your client.

      Note

      If you use Microsoft services, then your MicrosoftAppId when you created your bot.
      If you use another OAuth 2.0 service provider, then the client ID provided to you.

    4. Scopes
      The resources you are accessing.

      Note

      Your resource provider informs you about the resources to which you are requesting.
      The scopes must be space delimited.
      Example: Microsoft Graph, you may set User.Read.All.

      Note

      A third-party service, you may set anything.

    5. Authorization URL
      Your OAuth Authorization URL.

      https://login.microsoftonline.com/common/oauth2/v2.0/authorize
      

      Note

      Replace common with your Azure AD tenant ID if you are restricting the resources to an organization.

    6. Token options
      Response method. The HTTP verb for the response.

      POST

    7. Grant type
      Response type. The OAuth flow for the response.
      Authorization code

      Note

      The code flow is easier than token flow.
      For more information, visit the OAuth 2.0 Authorization Framework page.

    8. Token URL

      https://login.microsoftonline.com/common/oauth2/v2.0/token
      

      Note

      If you are restricting the resources to an organization, then replace common with your Azure AD tenant ID.

    9. Client secret

      Note

      If you use Microsoft services, then your MicrosoftAppPassword when you created your bot.
      If you use another OAuth 2.0 service provider, then the client secret provided to you. Your provider may use different terminology.
      Example: consumer secret.

    10. Client authorization scheme

    `Credentials in request body`
    
    >[!NOTE]
    > The `Credentials in request body` scheme is the most common way to send the identity payload.  
    
    1. Intranet authentication | checkbox
      If your Cortana Skill requires access to or through an intranet, then select this option.
  7. Click on the Connect to Cortana link.

    Important

    Visit your service provider site to grant access to the resources.

    • For Microsoft: Visit the My applications portal and select your Cortana Skill.

      • Click Add Platform, click Web, verify that you registered your redirect URL for Cortana, and then save your changes. You do not need a sign-out URL.

        Add Platforms

    • For Other service providers: Refer to the documentation from your service provider about allowing the redirect callback.

  8. Cortana should open a dialog window to sign in before opening your Cortana Skill. Microsoft recommends that you verify that your Cortana Skill has an access token.

    Each message includes an entity that includes the access token. If the access token is not present or if the access token property is empty, then it means you have not authenticated. The access token may be empty if the access token expires. When the access token expires, the correct solution is to display an OAuthCard to reacquire a token.

    Example: How to get your access token using C#.

    // Is the user authenticated?
    string authAccessToken = String.Empty;
    
    if (activity.Entities != null) {
        foreach (var entity in activity.Entities) {
            if (entity.Type == "AuthorizationToken") {
                dynamic authResult = entity.Properties;
                authAccessToken = authResult.token;
            }
        }
    }  
    

    Example: How to get your access token using Node.js.

    // Get access token from Cortana request
    var tokenEntity = session.message.entities.find((e) => {
            return e.type === 'AuthorizationToken';
        }
    );
    

    If the token is empty or if you selected the auth on demand option, then you may construct an OAuthCard for Cortana to request a sign-in.

    Example: Request a sign-in with an OAuthCard for Cortana using C#.

    private Activity CreateOAuthCard( Activity activity )
    {
        Activity message = activity.CreateReply();
        if (message.Attachments == null) {
            message.Attachments = new List<Attachment>();
        }
    
        // Create the attachment.
        Attachment attachment = new Attachment() {
            ContentType = OAuthCard.ContentType,
            Content = new OAuthCard();// Cortana ignores any card configuration
        };
    
        message.Attachments.Add(attachment);
        return message;
    }
    

    Example: Request a sign-in with an OAuthCard for Cortana using Node.js.

    var msg = new builder.Message(session).addAttachment( new builder.OAuthCard(session) );
    

    Example: How to add your access token to your resource request using C#.

    C#
    var url = "https://graph.microsoft.com/v1.0/me/contacts?select=birthday,nickName,surname,givenName";
    using (var client = new HttpClient()) {
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + authAccessToken); 
        var response = await client.GetAsync(url);
    
        …
    

    Example: How to add your access token to your resource request using Node.js.

    var url = 'https://graph.microsoft.com/v1.0/me/contacts?select=birthday,nickName,surname,givenName';
    request.get(url, (err, response, body) => {
    … }).setHeader('Authorization', 'Bearer ' + tokenEntity.token); // sets the auth token
    

    Note

    You should check for errors and HTTP status codes on the OAuth card.
    Example:

    401 unauthorized
    

Next Steps

If you use a Microsoft service that requires users with Microsoft accounts and looking for more information about configuring Connected Account channel settings for Microsoft identity server, then visit the Configure authentication for Microsoft identity server page.