{"id":16485,"date":"2017-12-09T19:42:00","date_gmt":"2017-12-09T19:42:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/premier_developer\/?p=16485"},"modified":"2019-07-29T11:29:54","modified_gmt":"2019-07-29T18:29:54","slug":"amazon-alexa-skills-authenticated-by-azure-active-directory-and-backed-by-asp-net-core-2-0-web-api-hosted-on-azure","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/premier-developer\/amazon-alexa-skills-authenticated-by-azure-active-directory-and-backed-by-asp-net-core-2-0-web-api-hosted-on-azure\/","title":{"rendered":"Amazon Alexa Skills authenticated by Azure Active Directory and backed by ASP.NET Core 2.0 Web API hosted on Azure"},"content":{"rendered":"<p>This post is provided by Premier Field Engineer, <a href=\"https:\/\/www.linkedin.com\/in\/nathan-vanderby-92a19814\/\">Nathan Vanderby<\/a>, who walks us through how to write an Alexa skill using .NET core and AAD.\u00a0 <strong>Lasted updated, June 2018.<\/strong><\/p>\n<hr \/>\n<p>Amazon&#8217;s Echo devices and Alexa assistant need no introduction. In this post I lay out how you can write an Alexa skill and use a .NET core 2.0 API backend service to handle the requests. We will also show how to leverage Azure Active Directory (AAD) so these calls can be authenticated and your users can get a personalized experience. <a href=\"https:\/\/www.linkedin.com\/in\/robmreilly\">Rob Reilly<\/a> has a great write up on how to accomplish this <a href=\"https:\/\/blogs.msdn.microsoft.com\/premier_developer\/2016\/12\/12\/amazon-alexa-skills-development-with-azure-active-directory-and-asp-net-core-1-0-web-api\/\">using .NET Core 1.0<\/a>. Here we&#8217;ll update the tutorial to .NET Core 2.0, simplify the code with <a href=\"https:\/\/github.com\/timheuer\/alexa-skills-dotnet\">Alexa.NET<\/a> NuGet package and fix a bug in his JWT middleware.<\/p>\n<p>There are four main items that need to be configured, the Alexa Skill in <a href=\"https:\/\/developer.amazon.com\/\">Amazon&#8217;s developer portal<\/a>, an <a href=\"https:\/\/azure.microsoft.com\/en-us\/services\/app-service\/\">Azure App. Service<\/a>, your <a href=\"https:\/\/www.microsoft.com\/net\/download\/core\">.NET Core 2.0<\/a> API, and <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/active-directory\/\">Azure Active Directory<\/a>. Once these items are configured a user just needs to add the skill in their Alexa app, use Alexa app or website to link their devices to their AAD and then they can start sending skill requests!<\/p>\n<p><strong>Components of an Alexa Skill<\/strong><\/p>\n<ul>\n<li>A set of <strong>intents<\/strong> that represent actions that users can do with your skill. These intents represent the core functionality for your skill.<\/li>\n<li>A set of sample <strong>utterances<\/strong> that specify the words and phrases users can say to invoke those intents. You map these utterances to your intents. This mapping forms the interaction model for the skill.<\/li>\n<li>An <strong>invocation name<\/strong> that identifies the skill. The user includes this name when initiating a conversation with your skill.<\/li>\n<li>A <strong>cloud-based service<\/strong> that accepts these intents as structured requests and then acts upon them. This service must be accessible over the Internet. You provide an endpoint for your service when configuring the skill.<\/li>\n<li>A <strong>configuration<\/strong> that brings all of the above together so that Alexa can route requests to the service for your skill. You create this configuration in the Alexa developer portal.<\/li>\n<\/ul>\n<h4>Step-by-step tutorial<\/h4>\n<h5>Step 1: Create an Azure Subscription<\/h5>\n<p>If you haven&#8217;t already signed up for Azure you can do so <a href=\"https:\/\/azure.microsoft.com\/en-us\/pricing\/purchase-options\/\">here<\/a>. This tutorial can be done using only free services. There is a free tier for Azure App. Service, Azure Active Directory App. registrations are free and Amazon doesn&#8217;t charge for creating a skill.<\/p>\n<h5>Step 2: Create your API<\/h5>\n<p>In this step we&#8217;ll create the API app and configure it to authenticate with Azure Active Directory. You can always configure the authentication manually, or simply use the Visual Studio API App template wizard to handle the heavy lifting for you. I&#8217;m going to use the wizard and I&#8217;ll point out all of the changes it is doing behind the scenes.<\/p>\n<p>First create a new project and select <strong>ASP.NET Core Web Application<\/strong> as the template.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37497\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard1.png\" alt=\"\" width=\"1645\" height=\"459\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard1.png 1645w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard1-300x84.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard1-768x214.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard1-1024x286.png 1024w\" sizes=\"(max-width: 1645px) 100vw, 1645px\" \/><\/p>\n<p>Make sure your creating an ASP.NET Core 2.0 template, then select <strong>Change Authentication<img decoding=\"async\" class=\"alignnone size-full wp-image-37498\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard2.png\" alt=\"\" width=\"1376\" height=\"574\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard2.png 1376w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard2-300x125.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard2-768x320.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard2-1024x427.png 1024w\" sizes=\"(max-width: 1376px) 100vw, 1376px\" \/>\n<\/strong><\/p>\n<p>Select from one of your Azure AD domains. Check <strong>Read directory data<\/strong>.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37499\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard3.png\" alt=\"\" width=\"1265\" height=\"623\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard3.png 1265w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard3-300x148.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard3-768x378.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/VSWizard3-1024x504.png 1024w\" sizes=\"(max-width: 1265px) 100vw, 1265px\" \/><\/p>\n<p>The authentication wizard automatically makes changes to 4 files, Startup.cs, AzureAdAuthenticaitonBuilderExtensions.cs, appsettings.json and ValuesController.cs.<\/p>\n<p>In <strong>Startup<\/strong> it tells the app to use AAD with the JWT bearer authentication scheme and IIS to use authentication middleware.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37500\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode1.png\" alt=\"\" width=\"1289\" height=\"740\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode1.png 1289w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode1-300x172.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode1-768x441.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode1-1024x588.png 1024w\" sizes=\"(max-width: 1289px) 100vw, 1289px\" \/><\/p>\n<p>In <strong>AzureAdServiceCollectionExtensions<\/strong> it defines the AddAzureAdBearer as a JwtBearer and sets the Audience and Authority properties for this application to trust and validate the token against.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37501\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode2.png\" alt=\"\" width=\"1694\" height=\"758\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode2.png 1694w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode2-300x134.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode2-768x344.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode2-1024x458.png 1024w\" sizes=\"(max-width: 1694px) 100vw, 1694px\" \/><\/p>\n<p>In the <strong>appsettings.json<\/strong> it automatically populates your Azure AD information including: Instnace, Domain, TenantId and ClientId. From the screenshot above we can see that that ClientId is being used as the audience value.<\/p>\n<p><code>options.Audience = _azureOptions.ClientId;\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37502\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode3.png\" alt=\"\" width=\"701\" height=\"188\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode3.png 701w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode3-300x80.png 300w\" sizes=\"(max-width: 701px) 100vw, 701px\" \/><\/code><\/p>\n<p>&nbsp;<\/p>\n<p>If you choose to configure authentication manually these settings come from as follows:<\/p>\n<dl>\n<dd>Instance &#8211; Azure AD login URL. This is dependent on the Azure cloud you are in. Commercial Azure, Azure Government, China &amp; Germany have different URLs.<\/dd>\n<dd>Domain &#8211; This is the AD tenant name where the app is registered.<\/dd>\n<dd>Tenant ID &#8211; This is your Azure subscription tenant id\/Azure AD Directory ID. This can be found in the Properties blade of Azure Active Directory resource.<\/dd>\n<dd>Client ID &#8211; This is unique to the application. It is found in the app registration blade of Azure Active Directory.<\/dd>\n<\/dl>\n<p>To find out your Tenant ID go to <strong>Azure Active Directory<\/strong> resource and select <strong>Properties\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37503\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup1.png\" alt=\"\" width=\"995\" height=\"796\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup1.png 995w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup1-300x240.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup1-768x614.png 768w\" sizes=\"(max-width: 995px) 100vw, 995px\" \/>\n<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>To get to the client ID (Audience value), go to <strong>Azure Active Directory<\/strong> resource and select <strong>App registrations<\/strong> and select your app registration.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37504\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup2.png\" alt=\"\" width=\"1383\" height=\"501\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup2.png 1383w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup2-300x109.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup2-768x278.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup2-1024x371.png 1024w\" sizes=\"(max-width: 1383px) 100vw, 1383px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>You can copy the application ID from the app registration list or click the &#8220;Click to Copy&#8221; icon next to the application ID on the app registration details page.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37505\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup3.png\" alt=\"\" width=\"516\" height=\"186\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup3.png 516w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup3-300x108.png 300w\" sizes=\"(max-width: 516px) 100vw, 516px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>In the <strong>ValuesController<\/strong> class it&#8217;s important to note the <strong>[Authorize]<\/strong> attribute on the controller. This attribute means only authenticated (and authorized users if roles are defined) can call these methods. This attribute can also be applied at the method level.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37506\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode4.png\" alt=\"\" width=\"573\" height=\"151\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode4.png 573w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/TemplateCode4-300x79.png 300w\" sizes=\"(max-width: 573px) 100vw, 573px\" \/><\/p>\n<p>Now that your application is configured to leverage Azure Active Directory we need to add code to handle the Alexa request. To start, add the <strong>Alexa.NET<\/strong> NuGet Package <a href=\"https:\/\/github.com\/timheuer\/alexa-skills-dotnet\">https:\/\/github.com\/timheuer\/alexa-skills-dotnet<\/a>\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37507\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaNetNuget.png\" alt=\"\" width=\"2031\" height=\"331\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaNetNuget.png 2031w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaNetNuget-300x49.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaNetNuget-768x125.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaNetNuget-1024x167.png 1024w\" sizes=\"(max-width: 2031px) 100vw, 2031px\" \/><\/p>\n<p>Then, alter your <strong>ValuesController<\/strong> to accept a <strong>SkillRequest<\/strong> and return a <strong>SkillRepsonse<\/strong> from a Post method like so:<\/p>\n<pre><code>[Authorize]\r\n[Route(\"api\/[controller]\")]\r\npublic class ValuesController : Controller\r\n{\r\n    [HttpPost]\r\n    public SkillResponse Post([FromBody]SkillRequest request)\r\n    {\r\n        SkillResponse response = null;\r\n        if (request != null)\r\n        {\r\n            PlainTextOutputSpeech outputSpeech = new PlainTextOutputSpeech();\r\n            string firstName = (request.Request as IntentRequest)?.Intent.Slots.FirstOrDefault(s =&gt; s.Key == \"FirstName\").Value.Value;\r\n            outputSpeech.Text = \"Hello \" + firstName;\r\n            response = ResponseBuilder.Tell(outputSpeech);\r\n        }\r\n\r\n        return response;\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>Without the <strong>[Authorize]<\/strong> attribute this code will work without account linking. Alexa sends the authentication token in the body of the request whereas the Authorize attribute expects it to be in the Authorization header. There are numerous ways to handle this. We will address this by adding a piece of middleware to automatically look at each request and if the body contains an authorization token then move it to the header. This allows the default authentication middleware to work seamlessly.<\/p>\n<p>Create a new class called <strong>AlexaJwtMiddleware<\/strong> and copy the code below in. It&#8217;s fairly straightforward and heavily commented. Its sole responsibility is to search through the request and move the authentication token from the body to the authorization header.<\/p>\n<pre><code>public class AlexaJWTMiddleware\r\n{\r\n    private readonly RequestDelegate _next;\r\n\r\n    public AlexaJWTMiddleware(RequestDelegate next)\r\n    {\r\n        _next = next;\r\n    }\r\n\r\n    public async Task Invoke(HttpContext context)\r\n    {\r\n        if (context.Request.Headers.Keys.Contains(\"Authorization\"))\r\n        {\r\n            await _next(context);\r\n            return;\r\n        }\r\n\r\n        \/\/ Keep the original stream in a separate\r\n        \/\/ variable to restore it later if necessary.\r\n        var stream = context.Request.Body;\r\n\r\n        \/\/ Optimization: don't buffer the request if\r\n        \/\/ there was no stream or if it is rewindable.\r\n        if (stream == Stream.Null || stream.CanSeek)\r\n        {\r\n            await _next(context);\r\n            return;\r\n        }\r\n\r\n        try\r\n        {\r\n            using (var buffer = new MemoryStream())\r\n            {\r\n                \/\/ Copy the request stream to the memory stream.\r\n                await stream.CopyToAsync(buffer);\r\n                byte[] bodyBuffer = new byte[buffer.Length];\r\n                buffer.Position = 0L;\r\n                buffer.Read(bodyBuffer, 0, bodyBuffer.Length);\r\n                string body = Encoding.UTF8.GetString(bodyBuffer);\r\n\r\n                if (!string.IsNullOrEmpty(body))\r\n                {\r\n                    SkillRequest request = JsonConvert.DeserializeObject&lt;SkillRequest&gt;(body);\r\n                    if (request.Session.User.AccessToken != null)\r\n                    {\r\n                        context.Request.HttpContext.Request.Headers[\"Authorization\"] = $\"Bearer {request.Session.User.AccessToken}\";\r\n                    }\r\n                }\r\n\r\n                \/\/ Rewind the memory stream.\r\n                buffer.Position = 0L;\r\n\r\n                \/\/ Replace the request stream by the memory stream.\r\n                context.Request.Body = buffer;\r\n\r\n                \/\/ Invoke the rest of the pipeline.\r\n                await _next(context);\r\n            }\r\n        }\r\n        finally\r\n        {\r\n            \/\/ Restore the original stream.\r\n            context.Request.Body = stream;\r\n        }\r\n    }\r\n}\r\n\r\n\/\/ Extension method used to add the middleware to the HTTP request pipeline.\r\npublic static class AlexaJWTMiddlewareExtensions\r\n{\r\n    public static IApplicationBuilder UseAlexaJWTMiddleware(this IApplicationBuilder builder) =&gt; builder.UseMiddleware&lt;AlexaJWTMiddleware&gt;();\r\n}\r\n<\/code><\/pre>\n<p>Finally we need to tell the <strong>Startup<\/strong> class to also use this middleware. Inside of Startup.cs <strong>Configure()<\/strong> method add a line <strong>before<\/strong> the authentication middleware. Order is important here as we need our new middleware to move the token before the authentication middleware searches for it to validate it.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37508\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/UseJWTMiddlewareCode.png\" alt=\"\" width=\"944\" height=\"305\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/UseJWTMiddlewareCode.png 944w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/UseJWTMiddlewareCode-300x97.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/UseJWTMiddlewareCode-768x248.png 768w\" sizes=\"(max-width: 944px) 100vw, 944px\" \/><\/p>\n<h5>Step 3: Publish to Azure<\/h5>\n<p>Now that your application has the proper code we need to publish it to Azure. There are a myriad ways to do this. One of the simplest is to right click on the project and select publish. Then follow the wizard to deploy to an App Service.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37509\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/PublishWizard1.png\" alt=\"\" width=\"685\" height=\"293\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/PublishWizard1.png 685w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/PublishWizard1-300x128.png 300w\" sizes=\"(max-width: 685px) 100vw, 685px\" \/><\/p>\n<p>On the first screen either create a new app service or use an existing one if you already have one setup.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37510\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/PublishWizard2.png\" alt=\"\" width=\"923\" height=\"520\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/PublishWizard2.png 923w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/PublishWizard2-300x169.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/PublishWizard2-768x433.png 768w\" sizes=\"(max-width: 923px) 100vw, 923px\" \/><\/p>\n<p>Then fill in the info for your existing or new app service. When finished click <strong>Ok\/Create<\/strong> then <strong>Publish\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37511\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/PublishWizard3.png\" alt=\"\" width=\"981\" height=\"400\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/PublishWizard3.png 981w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/PublishWizard3-300x122.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/PublishWizard3-768x313.png 768w\" sizes=\"(max-width: 981px) 100vw, 981px\" \/>\n<\/strong><\/p>\n<h5>Step 4: Configure the Alexa Skill<\/h5>\n<p>Now that we have our code in Azure we need to configure the Alexa skill. Navigate to <a href=\"https:\/\/developer.amazon.com\/alexa\">Amazon&#8217;s developer<\/a> page for Alexa, you will have to create an account. Navigate to <strong>Alexa Skills Kit -&gt; Get Started -&gt; Alexa Skills Kit<\/strong>.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37512\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkill1.png\" alt=\"\" width=\"468\" height=\"174\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkill1.png 468w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkill1-300x112.png 300w\" sizes=\"(max-width: 468px) 100vw, 468px\" \/><\/p>\n<p>Select <strong>Start a Skill<\/strong> then <strong>Create Skill<\/strong>.<\/p>\n<p>Give the skill a name, click next. Select the <strong>Custom<\/strong> model then click <strong>Create Skill<\/strong>.<\/p>\n<h6>Invocation<\/h6>\n<p>Select <strong>Invocation<\/strong> and enter a phrase to invoke your skill. Click <strong>Save<\/strong> then <strong>Next<\/strong> to move onto the Interaction Model.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37513\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillInvocation.png\" alt=\"\" width=\"568\" height=\"342\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillInvocation.png 568w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillInvocation-300x181.png 300w\" sizes=\"(max-width: 568px) 100vw, 568px\" \/><\/p>\n<h6>Intents<\/h6>\n<p>Select the <strong>Add<\/strong> button next to <strong>Intents<\/strong> and give the intent a name. We will use Tutorial.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37514\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillIntent.png\" alt=\"\" width=\"912\" height=\"122\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillIntent.png 912w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillIntent-300x40.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillIntent-768x103.png 768w\" sizes=\"(max-width: 912px) 100vw, 912px\" \/><\/p>\n<p>Type in a sample utterance such as <code>Can you greet {FirstName}<\/code> and click <strong>Add<\/strong> to create the sample utterance and the <code>FirstName<\/code> slot.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37515\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillSampleUtterance.png\" alt=\"\" width=\"491\" height=\"392\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillSampleUtterance.png 491w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillSampleUtterance-300x240.png 300w\" sizes=\"(max-width: 491px) 100vw, 491px\" \/><\/p>\n<p>The intent here is so Alexa knows that when we talk to &#8220;Tutorial&#8221; it should also expect a parameter called FirstName. If you look back at the code in the API Post method you will see how we can read the FirstName slot from the Tutorial intent on the request.<\/p>\n<p>Make sure the <code>FirstName<\/code> slot has a type of <code>Amazon.DE_FIRST_NAME<\/code>.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37516\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillIntentSlot.png\" alt=\"\" width=\"1069\" height=\"190\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillIntentSlot.png 1069w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillIntentSlot-300x53.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillIntentSlot-768x137.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillIntentSlot-1024x182.png 1024w\" sizes=\"(max-width: 1069px) 100vw, 1069px\" \/><\/p>\n<p>In the JSON Editor your skill should look like<\/p>\n<pre><code>{\r\n    \"interactionModel\": {\r\n        \"languageModel\": {\r\n            \"invocationName\": \"Tutorial\",\r\n            \"intents\": [\r\n                {\r\n                    \"name\": \"Tutorial\",\r\n                    \"slots\": [\r\n                        {\r\n                            \"name\": \"FirstName\",\r\n                            \"type\": \"AMAZON.DE_FIRST_NAME\"\r\n                        }\r\n                    ],\r\n                    \"samples\": [\r\n                        \"Can you greet {FirstName}\"\r\n                    ]\r\n                },\r\n                {\r\n                    \"name\": \"AMAZON.HelpIntent\",\r\n                    \"samples\": []\r\n                },\r\n                {\r\n                    \"name\": \"AMAZON.StopIntent\",\r\n                    \"samples\": []\r\n                }\r\n            ],\r\n            \"types\": []\r\n        }\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>Click <strong>Save Model<\/strong> and then <strong>Build Model<\/strong><\/p>\n<h5>Interfaces<\/h5>\n<p>Here you can add various interfaces. We won&#8217;t be using any of these. The various options for these are Audio Player, Display Interface, Video App, Alexa Gadget, etc.<\/p>\n<h6>Endpoint<\/h6>\n<p>Select <strong>HTTPS<\/strong> for the endpoint. Under the <strong>Default Region<\/strong> text box enter the URL for your API method.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37517\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillEndpoint.png\" alt=\"\" width=\"1000\" height=\"290\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillEndpoint.png 1000w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillEndpoint-300x87.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaSkillEndpoint-768x223.png 768w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<p>Select <strong>My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority<\/strong> from the drop down.<\/p>\n<h6>Account Linking<\/h6>\n<p>In the Account Linking section enable the slider. Enter the following information into the fields:<\/p>\n<ul>\n<li>Authorization Grant Type: <strong>Auth Code Grant<\/strong><\/li>\n<li>Authorization URI: <a href=\"https:\/\/login.microsoftonline.com\/**%7BTenantId\/DirectoryId%7D**\/oauth2\/authorize?resource=**%7BApplication\">https:\/\/login.microsoftonline.com\/**{TenantId\/DirectoryId}**\/oauth2\/authorize?resource=**{Application<\/a> ID}**\nThe TenandId\/DirectoryId is the same GUID that is in the appsettings.json config file. The Application ID is the Application ID from the app registration. This parameter is required by Azure AD and it tells AAD which resource Alexa is requesting access to and defines the audience property in the JWT token returned from AAD. According to the documentation <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/active-directory\/develop\/active-directory-protocols-oauth-code\">here<\/a> the resource parameter is only recommended, but if you debug account linking with Postman you will notice it fails and states the resource parameter is required.<\/li>\n<li>Client Id: This is the Application Id from the app registration\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37518\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup3-2.png\" alt=\"\" width=\"516\" height=\"186\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup3-2.png 516w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AADWizardSetup3-2-300x108.png 300w\" sizes=\"(max-width: 516px) 100vw, 516px\" \/><\/li>\n<li>Access Token URI: <a href=\"https:\/\/login.windows.net\/**%7BTenantId\/DirectoryId%7D**\/oauth2\/token\">https:\/\/login.windows.net\/**{TenantId\/DirectoryId}**\/oauth2\/token<\/a> This URI can be found in the Endpoints settings of the app registration blade. Copy the <strong>OAUTH 2.0 TOKEN ENDPOINT\n<\/strong> <img decoding=\"async\" class=\"alignnone size-full wp-image-37519\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking2.png\" alt=\"\" width=\"1207\" height=\"537\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking2.png 1207w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking2-300x133.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking2-768x342.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking2-1024x456.png 1024w\" sizes=\"(max-width: 1207px) 100vw, 1207px\" \/>\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37520\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking3.png\" alt=\"\" width=\"502\" height=\"985\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking3.png 502w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking3-153x300.png 153w\" sizes=\"(max-width: 502px) 100vw, 502px\" \/><\/li>\n<li>Client Secret: This is effectively the password the Alexa service will use to allow account linking to your API backend. We will generate one now. Navigate to the <strong>Keys<\/strong> setting in the API app registration.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37521\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking4.png\" alt=\"\" width=\"1575\" height=\"620\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking4.png 1575w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking4-300x118.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking4-768x302.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking4-1024x403.png 1024w\" sizes=\"(max-width: 1575px) 100vw, 1575px\" \/>\nGive a key a description and a duration. <strong>Select a 1 or 2 year duration.<\/strong> A key with &#8220;never expires&#8221; duration may fail account linking. Click <strong>Save<\/strong>. The key will be generated on the save. This will be the one time this key is displayed, so copy it.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37522\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking5.png\" alt=\"\" width=\"741\" height=\"254\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking5.png 741w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking5-300x103.png 300w\" sizes=\"(max-width: 741px) 100vw, 741px\" \/><\/li>\n<li>Client Authentication Scheme: HTTP Basic (Recommended)<\/li>\n<\/ul>\n<p>In the end your Account Linking settings should look similar to this:\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37523\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking6.png\" alt=\"\" width=\"1382\" height=\"630\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking6.png 1382w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking6-300x137.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking6-768x350.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinking6-1024x467.png 1024w\" sizes=\"(max-width: 1382px) 100vw, 1382px\" \/><\/p>\n<p>Before we move onto the next screen, notice the <strong>Redirect URIs<\/strong> in the settings. Copy these URLs into the Redirect URLs setting for app registration. This replaces the one we used earlier that had in it.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37524\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinkingRedirectURI1.png\" alt=\"\" width=\"806\" height=\"230\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinkingRedirectURI1.png 806w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinkingRedirectURI1-300x86.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinkingRedirectURI1-768x219.png 768w\" sizes=\"(max-width: 806px) 100vw, 806px\" \/>\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37525\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinkingRedirectURI2.png\" alt=\"\" width=\"1090\" height=\"205\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinkingRedirectURI2.png 1090w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinkingRedirectURI2-300x56.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinkingRedirectURI2-768x144.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/AlexaAccountLinkingRedirectURI2-1024x193.png 1024w\" sizes=\"(max-width: 1090px) 100vw, 1090px\" \/><\/p>\n<h5>Step 6: Link Accounts and Test<\/h5>\n<ol>\n<li>Login to https:\/\/alexa.amazon.com<\/li>\n<li>Navigate to <strong>Skills<\/strong> -&gt; <strong>Your Skills<\/strong><\/li>\n<li>You should see our newly created skill. Click on it.\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37526\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts1.png\" alt=\"\" width=\"457\" height=\"284\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts1.png 457w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts1-300x186.png 300w\" sizes=\"(max-width: 457px) 100vw, 457px\" \/><\/li>\n<li>Select <strong>SETTINGS\n<\/strong><img decoding=\"async\" class=\"alignnone size-full wp-image-37527\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts2.png\" alt=\"\" width=\"1762\" height=\"416\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts2.png 1762w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts2-300x71.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts2-768x181.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts2-1024x242.png 1024w\" sizes=\"(max-width: 1762px) 100vw, 1762px\" \/><\/li>\n<li>Click on the <strong>Link Account<\/strong> button in the upper right corner\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37528\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts3.png\" alt=\"\" width=\"1750\" height=\"212\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts3.png 1750w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts3-300x36.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts3-768x93.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts3-1024x124.png 1024w\" sizes=\"(max-width: 1750px) 100vw, 1750px\" \/><\/li>\n<li>You will be redirected to login to Azure Active Directory and then asked to accept the access being requested. Once you get through that result and if all goes well you should see:\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37529\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts4.png\" alt=\"\" width=\"475\" height=\"196\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts4.png 475w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/LinkAccounts4-300x124.png 300w\" sizes=\"(max-width: 475px) 100vw, 475px\" \/><\/li>\n<\/ol>\n<p>If you are unsuccessful linking your account see the troubleshooting steps below.<\/p>\n<h5>Step 7: Testing<\/h5>\n<p>We have multiple options by which to test the Alexa Integration. We can use an actual device or the Amazon Developers Portal Test client.<\/p>\n<p><strong>Amazon Developer Portal<\/strong><\/p>\n<ol>\n<li>In the Amazon Developer portal where we configured the Alexa skill <em>Note: If you left this tab open from the prior instructions, you will have to refresh the page after performing the account linking<\/em><\/li>\n<li>Make sure you are under the skill you are wanting to test<\/li>\n<li>Click on the test section<\/li>\n<li>In the Enter Utterance Section enter the following: <strong>ask Tutorial to greet <\/strong><\/li>\n<\/ol>\n<ul>\n<li>= any name<\/li>\n<li>This is derived in the <strong>Invocation Model<\/strong> section for the skill.<\/li>\n<\/ul>\n<ol>\n<li>If all goes well you should see something that looks like:\n<img decoding=\"async\" class=\"alignnone size-full wp-image-37530\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/Testing.png\" alt=\"\" width=\"1304\" height=\"430\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/Testing.png 1304w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/Testing-300x99.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/Testing-768x253.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2017\/12\/Testing-1024x338.png 1024w\" sizes=\"(max-width: 1304px) 100vw, 1304px\" \/><\/li>\n<\/ol>\n<ul>\n<li>if you get a <code>401: Unauthorized<\/code> result check that the skill is account linked or see some debugging tips below.<\/li>\n<\/ul>\n<h4>Troubleshooting<\/h4>\n<ul>\n<li>Double check Web App settings in Azure aren&#8217;t overriding the web.config settings<\/li>\n<li>F12 browser tool\n<ul>\n<li>If you need to look at the HTTP Request Response stream pressing F12 from Explorer, Edge, Chrome will open integrated developer tools.<\/li>\n<\/ul>\n<\/li>\n<li>JWT.IO &#8211; https:\/\/jwt.io\/\n<ul>\n<li>This is a browser based tool where you can take your JWT token from the request and decode it and verify the signature<\/li>\n<\/ul>\n<\/li>\n<li>If account linking works and your still getting a <code>401 unauthorized<\/code> response try the following:\n<ul>\n<li>Refresh the Amazon develop page and try again (this makes Amazon request a new token)<\/li>\n<li>Check the skill is successfully account linked.<\/li>\n<\/ul>\n<\/li>\n<li>Enabling diagnostic logs, detailed error messages and leveraging live streaming of logs in the Azure portal for the web app is very useful for debugging<\/li>\n<li>Use Postman to troubleshoot account linking problems. A video on how to do this can be found <a href=\"https:\/\/blogs.msdn.microsoft.com\/devkeydet\/2016\/03\/22\/using-postman-with-azure-ad\/\">here<\/a>.<\/li>\n<\/ul>\n<h4>Sample Code<\/h4>\n<p>The companion source code for the web API portion of this tutorial can be located on GitHub at <a href=\"https:\/\/github.com\/vanderby\/AlexaToAzureAPI\">https:\/\/github.com\/vanderby\/AlexaToAzureAPI<\/a><\/p>\n<h4>Links<\/h4>\n<ul>\n<li>Visual Studio and .NET Core API\u2019s\n<ul>\n<li><a href=\"https:\/\/www.microsoft.com\/net\">https:\/\/www.microsoft.com\/net<\/a><\/li>\n<\/ul>\n<\/li>\n<li>Azure SDKs and Tools\n<ul>\n<li><a href=\"https:\/\/azure.microsoft.com\/en-us\/downloads\/\">https:\/\/azure.microsoft.com\/en-us\/downloads\/<\/a><\/li>\n<li><a href=\"https:\/\/blogs.msdn.microsoft.com\/premier_developer\/2016\/12\/12\/amazon-alexa-skills-development-with-azure-active-directory-and-asp-net-core-1-0-web-api\/\">https:\/\/blogs.msdn.microsoft.com\/premier_developer\/2016\/12\/12\/amazon-alexa-skills-development-with-azure-active-directory-and-asp-net-core-1-0-web-api\/<\/a><\/li>\n<\/ul>\n<\/li>\n<li>ASP.NET Authentication attribute documentation\n<ul>\n<li><a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.web.mvc.authorizeattribute(v=vs.118).aspx\">https:\/\/msdn.microsoft.com\/en-us\/library\/system.web.mvc.authorizeattribute(v=vs.118).aspx<\/a><\/li>\n<\/ul>\n<\/li>\n<li>Amazon developer documentation\n<ul>\n<li><a href=\"https:\/\/developer.amazon.com\/alexa-skills-kit\">https:\/\/developer.amazon.com\/alexa-skills-kit<\/a><\/li>\n<\/ul>\n<\/li>\n<li>How to use Postman to debug account linking\n<ul>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/active-directory\/develop\/active-directory-protocols-oauth-code\">https:\/\/docs.microsoft.com\/en-us\/azure\/active-directory\/develop\/active-directory-protocols-oauth-code<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<hr \/>\n<p><a href=\"https:\/\/blogs.msdn.com\/b\/premier_developer\/archive\/2014\/09\/15\/welcome.aspx\"><strong>Premier Support for Developers<\/strong><\/a> provides strategic technology guidance, critical support coverage, and a range of essential services to help teams optimize development lifecycles and improve software quality.\u00a0 Contact your Application Development Manager (ADM) or <a href=\"https:\/\/blogs.msdn.microsoft.com\/premier_developer\/contact-us\/\"><b>email us<\/b><\/a> to learn more about what we can do for you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post is provided by Premier Field Engineer, Nathan Vanderby, who walks us through how to write an Alexa skill using .NET core and AAD.\u00a0 Lasted updated, June 2018. Amazon&#8217;s Echo devices and Alexa assistant need no introduction. In this post I lay out how you can write an Alexa skill and use a .NET [&hellip;]<\/p>\n","protected":false},"author":582,"featured_media":37840,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[25],"tags":[139,61,24,3],"class_list":["post-16485","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","tag-alexa","tag-asp-net-core","tag-azure","tag-team"],"acf":[],"blog_post_summary":"<p>This post is provided by Premier Field Engineer, Nathan Vanderby, who walks us through how to write an Alexa skill using .NET core and AAD.\u00a0 Lasted updated, June 2018. Amazon&#8217;s Echo devices and Alexa assistant need no introduction. In this post I lay out how you can write an Alexa skill and use a .NET [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/16485","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/users\/582"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/comments?post=16485"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/16485\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media\/37840"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media?parent=16485"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/categories?post=16485"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/tags?post=16485"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}