Allen Conway's Blog

Exploring all things .NET and beyond...

Using the Azure Mobile Apps Signing Key with JWT Bearer Authentication in ASP.NET Core

Azure Mobile Apps allow users to quickly get up and running using authentication via 3rd party providers. Once registered with your Azure Mobile Apps instance, you can use the appropriate SDK (i.e. JavaScript SDK) to authenticate users, and in turn get a signed JWT back representing the authenticated user and their claims. This JWT can be turned around and sent with requests to the server to authenticate users when making WebAPI calls.

This was also possible in the predecessor to Azure Mobile Apps, named Azure Mobile Services. The 'master' and 'application' keys were readily available from the Azure dashboard. The server receiving the JWT could use the 'master' key and check if the JWT being sent was issued using the identical key. If it was then that is an indicator that the call is properly authenticated.

With Azure Mobile Apps the concept of the 'master' and 'application' keys have been removed from the portal, as well the JavaScript SDK is no longer required to send the 'application' key in the calls to the server. However the concept of the 'signing' key that created the JWT representing the authenticated user still exists. The following steps will help you get started using Azure Mobile Apps and the JavaScript SDK, to call a WebAPI backend using ASP.NET Core.

1. Get the Signing Key for your Azure Mobile Apps Instance


If you want to use JWT Bearer Authentication on the server, you'll need to configure its settings to contain the Signing Key used to generate the JWT passed back to the authenticated client from Azure. This way you can validate calls on the server and that the user was truly authenticated via your Azure Mobile App instance. The nice thing about JSON Web Tokens is they are structured to contain known information (claims) including being able to verify the signing value used and if it matches. 

The signing value is unfortunantly buried on a page outside of the Azure portal. This wild goose chase I went on trying to find the value was a time dump, so hopefully with this information you'll be able to find this quickly. To get the signing key, go to the following URL (best if already signed into Azure):

https://{yoursite}.scm.azurewebsites.net/env
Replace the {yoursite} portion with the name of your Azure instance. A page will load with a ton of configuration about your site. Do a 'find' for the following value: 
WEBSITE_AUTH_SIGNING_KEY
The signing value will be associated with that key that is used for your Azure Mobile Apps instance. Grab it and save for use in the next step.



2. Configure JwtBearerAuthentication in ASP.NET Core

  1. Pull in the NuGet package via project.json in your WebAPI ASP.NET Core project. This will allow us to have the needed bits to configure the ASP.NET Core middleware for JWT Bearer Authentication:
  2. "Microsoft.AspNetCore.Authentication.JwtBearer": "1.1.0-preview1-final"
    
  3. To prevent making Startup.cs too polluted, create a separate partial class (if desired) named something like Startup.auth.cs where we can place the JWT middleware configuration. Then in the Configure method of the main Startup.cs file, add the following to call our new method we'll create below:
  4. ConfigureAuth(app);
    
  5. Add the JWT configuration, and replace the value in the instantiation of SymmetricSecurityKey with the value from your Azure instance we extracted above in Step #1. All of this configuration and setting of the various properties is up to you. At a minimum though I'd recommend making sure that the key was issued from the correct domain, not expired, and signed with the proper key. The key will need to be extracted from its hex value, so the helper is included.
  6. public partial class Startup
    {
    /// <summary>
    /// Sets up JWT middleware configuration for use when authorizing endpoints within this API
    /// </summary>
    /// <param name="app"></param>
    private void ConfigureAuth(IApplicationBuilder app)
    {
     //Todo: place in configuration
     var signingKey = new SymmetricSecurityKey(FromHex("YOUR_WEBSITE_AUTH_SIGNING_KEY_VALUE_HERE"));            
    
     var tokenValidationParameters = new TokenValidationParameters
     {
      RequireSignedTokens = true,
      RequireExpirationTime = true,
      SaveSigninToken = false,
      ValidateActor = false,
    
      // The signing key must match!
      ValidateIssuerSigningKey = true,
      IssuerSigningKey = signingKey,
        
      // Validate the JWT Issuer (iss) claim
      ValidateIssuer = true,
      ValidIssuer = "https://your-site.azurewebsites.net/",
    
      // Validate the JWT Audience (aud) claim
      ValidateAudience = true,
      ValidAudience = "https://your-site.azurewebsites.net/",
    
      // Validate the token expiry
      ValidateLifetime = false,
    
      // If you want to allow a certain amount of clock drift, set that here:
      ClockSkew = TimeSpan.Zero
     };
    
     app.UseJwtBearerAuthentication(new JwtBearerOptions
     {
      AutomaticAuthenticate = true,
      AutomaticChallenge = true,
      TokenValidationParameters = tokenValidationParameters
     });
    
    }
    
    /// <summary>
    /// Decodes a Hex string
    /// </summary>
    /// <param name="hex"></param>
    /// <returns>byte[]</returns>
    private static byte[] FromHex(string hex)
    {
     hex = hex.Replace("-", "");
     byte[] raw = new byte[hex.Length / 2];
     for (int i = 0; i < raw.Length; i++)
     {
      raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
     }
     return raw;
    }
    }
    
  7. Add the usual Authorize attribute to the API controllers where authentication needs to be enabled.
  8. [Authorize]
    
That's the basics of the setup. You'll want to configure the client to store the JWT retrieved after authenticating for the session of the user, and should be sent as a 'Bearer' Authorization header on the request. This will ensure that all of your calls from the JavaScript client to the WebAPI server instance will be authenticated properly. If the JWT passed in the request header for the call doesn't pass all the validations set in the ConfigureAuth method, the call will fail as desired with a 401 Unauthorized to the client.

I'm speaking at Modern Apps LIVE! Vegas + Free Webcast on 2/7

Please join me Tuesday, February 7 at 11am PT/2pm ET to preview Modern Apps LIVE! Vegas (a part of Visual Studio LIVE!), and my modern app web sessions via a free webcast. You can sign up at the following link: 

Viva Modern Web Development!

This will preview Modern Apps LIVE! (in partnership with Magenic), and the following session I'll be presenting:
You can also save $500 of the 5-day all-access Best Value Conference Package in Las Vegas (March 13-17) by using my speaker savings code of LVSPK09 when registering for the event. Just use the following link or click the image below.



Configure Azure Mobile App Authentication Server-Side for Use With JavaScript Clients

Azure Mobile Apps offer a great way to secure your application using OAuth and known 3rd party providers like Twitter, Facebook, Microsoft, and Google. This takes a lot of the manual authorization implementation requirements and shits responsibilities to these providers. This is a great way to secure you JavaScript web application quickly and without a lot of work. 

The focus of this post is to talk about the server-side security configurations required to allow your JS App to authenticate with the 3rd party providers, and then redirect back to your application successfully. If you want an overall tutorial on setting up the providers and working with the JavaScript SDK, see the following links: 
After the providers are configured for your Azure Mobile App instance, and you have the JavaScript SDK downloaded and being called from your JS Application there are (2) important server-side configurations required for allowing calling the the providers and redirecting back to your calling application successfully. Without these setting below, you'll probably get a HTTP 403 Forbidden error like the following after successfully authenticating:
You do not have permission to view this directory or page

1. Configure CORS

You'll need to whitelist your application URLs that are being called, so that after authenticating with the 3rd party provider it can callback successfully to your application with the user's information. This includes localhost values for testing on your dev machine. To configure CORS in Azure:
  1. Navigate to the Azure Portal
  2. Select your Azure Mobile App instance under Resources
  3. In the Search box type in CORS and select it from the results
  4. Enter in all of the applicable whitelist URLs including local dev values (note: no trailing slashes at the end or Azure will complain it is not a valid URL)
  5. Click Save at the top to save the changes

Note: You can use the "*" value to allow all domains and URLs but this is NOT advised as it nullifies this security aspect. The only time this is recommended is for debugging security issues to widen the allowable URLs to see if this fixes the problem. If this works, it's recommended to then remove and determine the missing values.

2. Configure External Redirect URLs

You'll need to whitelist the same loopback URLs used in the step above for redirect. Without these values you might successfully authenticate with the provider, but your pop-up window will display the "You do not have permission to view this directory or page" error and not finish back to the caller.
  1. Navigate to the Azure Portal
  2. Select your Azure Mobile App instance under Resources
  3. In the Search box type in Resource explorer, select it from the results and press "GO->" to launch the explorer (opens in a new tab/window)
  4. Click the + to expand the config section and select authsettings
  5. Click on the Edit button at the top
  6. Modify the allowedExternalRedirectUrls to contain an array of string values with your whitelist URLs including local dev testing URLs
  7. Click PUT at the top of the explorer to save the changes

To ensure my values were used, I preformed the additional step of selecting Restart from the Overview page of the Azure Mobile App instance since I was just in development (and not in prod). 


This may not be required, but I wanted to make sure everything was working as I had configured. Once these steps were completed, the authentication process worked successfully.

Ensuring TypeScript Files Are Served to the Browser for Debugging Using ASP.NET Core

I'm working on an ASP.NET Core site that's an Angular + TypeScript app leveraging all of the goodies in the new web template including the use of a task runner like Gulp. As I'm running my site I wanted to debug my TypeScript files in the Chrome debugger, but upon selecting the file it appeared blank. The .js files appeared correctly, but not the TypeScript files. There are just a few steps to follow to get the all the needed files to load into the browser properly.

1. Update startup.cs Configuration

Ensure the ASP.NET core application is set to serve up static files. To do this, configure the middleware to enable static files to be served to wwwroot. This makes wwwroot servable. You should also depending on the site your creating have the middleware configured to serve up a default home page to your base URL. Odds are you already had both of these steps complete or your site wouldn't even work, but to be thorough make sure you have the following in startup.cs:


2. Update tsconfig.json

If you are using tsconfig.json as well as a task runner like a gulp file, then you are probably leveraging tsconfig to build and transpile the TypeScript files and gulp to deploy them. If this is how you have your application setup, then you'll want to ensure that the sourcemap (.js.map) files are also generated. This will generate the .map files and add the proper reference at the bottom of the .js file to the corresponding map file. These map files let the debugger map between the emitted JavaScript code and the TypeScript files it was transpiled from originally. The .map reference will look like the following (you don't have to add this manually - it's just for reference):


In order to create the map file, make sure the following setting is in your tsconfig.json file and set to 'true':


3. Update gulp.js tasks

The last step is to ensure that the TypeScript files are copied out to your deployment target (i.e. wwwroot). Typically using gulp you'd have both development and release configurations. Ensure that for your dev settings or for whenever you want to debug TypeScript (.ts) files, you add a command to also copy out the TypeScript files as well. Normally only the .js files are needed by the browser, so often we'll overlook copying out the TypeScript files, but this is important so the browser has access and can display them correctly.


That should do it - now when you open the Chrome debugger and click on a TypeScript file it should load properly.

Is ASP.NET MVC the new WebForms because of Smart Client JS Web Apps?

In the last few years JavaScript, JavaScript frameworks, and the browser have matured exponentially providing us with AngularJS, React, Aurelia, Ember, and others. These frameworks allow for web developers to create performant and rich smart client JavaScript web applications (a.k.a SPAs). So what about ASP.NET and that old trustworthy MVC implementation? As an analogy, is MVC the new 'WebForms' as to how WebForms were viewed when MVC came to the scene? Is ASP.NET MVC obsolete or considered now 'old hat' from an implementation perspective? I think it is mostly 'yes' and just a bit of 'no' to that question and I'll provide points to both.



The bold answer is yes - MVC is a relic of days past and anyone that uses it has their head in the sand. Well maybe not quite and certainly not near being obsolete. However there is some merit to the fact that ASP.NET MVC is showing it's age as an implementation choice. There are many things that JS web applications do very well and architecturally speaking just make sense. 

To begin, the JS Frameworks by nature move the heavy rendering and presentation logic to the client. This removes the burden on the server of packaging both markup and data to send to the client. The server's main responsibility is now returning only data typically in the way of JSON payloads via RESTful services (i.e. NodeJS, WebAPI), as well as the web artifacts on an as needed basis (i.e. views, images, JS, etc.). With most frameworks, once the views and associated JS is brought to the client it is cached. The combination of client side processing + caching of data and website artifacts = highly performant web applications.

The 1st time most developers get accustomed to a JS Framework creating a web application, and experience how the line between desktop applications and web application almost is non-existent they often see the many benefits and don't look back.


Add atop of all this, most JS Frameworks were built with testing in mind, have massive adoption, huge amounts of support, examples, and training which adds up to something one can feel confident moving forward with as an implementation choice.

Another advantage of smart client JS Web Applications is the fact that they make sense architecturally. MVC by nature is and should be a presentation layer architecture. In ASP.NET MVC, I still see often the architecture abused and used as the full-blown implementation for Enterprise Applications. I don't blame most for doing this as the majority of  '101' examples show this implementation so it must be what is used for everything, right? Wrong. It's analogous for those of you that have used Angular 1.x and having the controller make $http calls directly, or abusing $scope as the do-all for the app. 

A tattle-tale sign of using MVC incorrectly is if the 'Model' is directly making database calls (i.e. EF or whatever) and then having the Controller make calls to methods on the Model. This then results in bloating either the model or controller (or both) with additional business logic or model hydration/shaping. MVC should be the top layer of the cake and only concerned with presentation layer logic and manipulation. JS Frameworks for the most part solve this problem naturally because of the separation now between the client and server. It's more difficult and many times not even possible to abuse the JS Web App client implementation that was done so often in ASP.NET MVC. Now one is forced to call the server for data, and then on the server another layered implementation can exist within the RESTful service to handle logic, rules, additional underlying calls, hydration/shaping, etc.. With a JS Web App we should relegate the MV* implementation client side to only presentation layer concerns, and allow the server to do what it does best and offer up reusable RESTful endpoints, encapsulating all server logic. With MVC this was absolutely possible, however it was typically a conscious decision and had to be made usually at the project's onset in order to have decent SoC and testability. Otherwise the result would be behemoth of a web application stuffed into the slim MVC implementation. 

From a JavaScript perspective my experience as a whole in MVC usually yielded to a jQuery implementation for DOM manipulation and a multi-thousand line file named MyApp.js. At 1st this file seems like a good idea, but then it snowballs into a intermingled mess of reactionary code responding to events, registering callbacks, making AJAX calls, manipulating views, and a hundred other things all interwoven together. Most of the time I saw no forethought put into proper segregation using known JS patterns like the module or revealing module pattern, and mostly a mess of public values and methods that were a ticking time bomb of heavy maintenance. In JS Framework implementations, there is a separation of concerns between the Model and View logic allowing testing and scaling your application more correctly. The alleviates the need for JS DOM manipulation libraries like jQuery all together.

Let's pile on another thing helping out JS Web apps in the way of languages like TypeScript.
This gem which was originally created at Microsoft by the same guy that created C# and is OSS, is a superset of JavaScript and adds on a slew of features to help developers wrangle some of the JavaScript nuances. There isn't anyone here claiming JavaScript is a perfect language, but I'll tell you from 1st hand experience using TypeScript makes creating JS Web apps in my experience a whole lot easier. Static typing, build time checking of code, Interfaces and other language features that don't exist in JS, staying ahead of the ECMAScript standards and releases, OO familiarity, and many other goodies help make TypeScript a real joy to have in the toolbox when creating JS Web Apps.


So now let's look at the flip side of the coin: ASP.NET MVC's advantages. Well to begin Microsoft is doing ASP.NET in general a whole world of good in the way of .NET Core 1.0. From a project's physical structure and implantation, the new world of the web in VS.NET is brought inline with where the rest of the web and OSS community has already been in the last several years. This is to the tune of task runners like Gulp or Grunt, additional package managers in the way of NPM and Bower, .json configuration for many different project components or languages like TypeScript, and several other new changes. 

The irony is from WebForms to MVC we moved from a 'Convention over Configuration' phase. Now we are shifting back to 'Configuration over Convention'. However this is in a very good way. Instead of getting many tools, resources, and processes being dictated and packaged up by default, you need to tell your web app exactly what you want and how you want it to behave from start to finish. This is a good thing. We as developers should have full control over our applications and dictate this configuration. At first this might cause some heartburn as change sometimes does, but it's the right move and I applaud Microsoft. For so long I used to promote how much I liked living inside the comfortable confines of ASP.NET and VS.NET. This magic thing like 'bundling and minification' was done for me along with many other tasks to get up and running. There is a little more work now as this doesn't even exist anymore in .NET Core 1.0, but I can control and configure my apps to be lean and behave as I want them to.


So wait, what about the good bits of MVC?? The above was like a back-handed compliment about MVC finally catching up to more standard methods of configuring web applications. However there are a couple of big things MVC still has going for it.

1st it's quite mature. ASP.NET has been around since 2001 and the MVC implementation since 07`. That's almost 10 years going strong. In addition Microsoft is behind it and is now OSS. It's not going anywhere, anytime soon. If your looking for that rock of stability and being conservative MVC is a good choice. Keep in mind though, ASP.NET WebForms is stable and around too, but that doesn't mean it's the best decision.

2nd, because of it's maturity there are a slew of developers that have experience with using it and developing application for it. There are just some realities that exist. Things like deadlines and financial constraints are legitimate concerns. As the lead, architect, decision maker, etc. on your team you might have 10 developers that are strong in MVC and have relatively no experience with a JS Framework and JavaScript in general with a deadline fast approaching. Do you bite the bullet and try your hand at creating a JS Web App, or go with old trusty and bang it out in MVC? That's a decision you'll need to make and one I've encountered as well.

To sum things up, I do believe JS Web Apps are here and probably the best decision for net new web apps today. I personally view MVC as a bit of a heavy weight in the web ring and sometimes we need something a bit more lean to fight our development battle. I agree for the most part MVC is beginning to be viewed as the new 'WebForms' as far as making an analogy to how WebForms were viewed when MVC came to the scene. However as I've broken it down, ASP.NET MVC isn't going anywhere and is still a fine choice to make in certain scenarios. 

Who knows, maybe I'll be writing this same article in 5 years with the following title:

"Are JS Web Apps the new MVC because of WebAssembly?"

Chutzpah and non-ES5 JavaScript for Unit Testing is Problematic

I've been working with Chutzpah for VS.NET as a test runner for my Jasmine JavaScript unit tests and ran into some issues that had me essentially stuck and running out of debugging options. I mined Matthew Manela's samples, GitHub repo, articles, log tracing, settings files, simple test harnesses, and many other trial and error event before finally determining the root cause of my headaches.

No matter how simple it seemed of a test harness I used in JavaScript to test using Chutzpah, I kept getting errors like the following: 
Can't find variable: myVariable in file xyz....
Normally this is an indication that the referenced JavaScript file is not properly referenced and the test cannot use it. Therefore the test fails and complains that a variable can't be resolved because ultimately the file is not referenced or not referenced properly. Or so it appears on the surface.

This is the red herring...



This led me on a path of vigorous path tracing, trying different path notation for referencing, using chutzpah.json files, running from the command line, debugging, refactoring, and on and on. No matter what I'd do I couldn't apparently get the file referenced for the unit test to run.

Naturally what makes this all worse was that if I open my JS tests in the browser using the default Jasmine Test Runner, they of course pass. So I know it's only a problem with Chutzpah running my tests.

I do the most basic of tests:

expect(true).toBeTruthy();

This passes. So at least I know VS.NET and Chutzpah can actually work together. 

Here is the crux of it and I'm not sure why it dawned on me but I decided to investigate my JS code. I had begun to sprinkle in some ES6 syntax that by now was compatible in most current browsers. Things like 'class' or 'for...of' loops. The problem is Chutzpah uses the PhantomJS headless browser to run the unit tests. It is based off the WebKit layout engine, so its about like running tests in Safari.

However I was completely wrong in this assumption. From the following (albeit an older package the reference still holds for this topic): 
"Most versions of PhantomJS do not support ES5, let alone ES6. This meant that you got all sorts of errors when you tried to test ES6 features, even if you had used the Babel/6to5 transpiler."
PhantomJS today appears strictly ES5 compliant and even a single line of ES6 syntax in your JS file will cause the referenced file not to be processed and thus serving up the error that it cannot be found. It can't be found because it can't be understood by PhantomJS. Hence the red herring about not being able to understand a variable being referenced in my test because the JS class could not be used.

I had one particular JS class I thought was 100% ES5 and this made the debugging even worse. The way I finally sniffed out some ES6 syntax was to drop it in a TypeScript file and target it to transpile to ES5 JS. When I compared the files side-by-side sure enough I found some ES6 syntax in my JS files. Once I ported the ES5 compliant JS over, Chutzpah and PhantomJS both worked perfectly and my tests passed within VS.NET.

I think the lessons learned here are the following:
  • PhantomJS which Chutzpah uses to run unit tests requires ES5 only JS, so make sure all of your JS is ES5 transpiled (Babel, TypeScript, etc.) and target these source files for the unit tests
  • If able to write and target ES6 features and browsers and not wanting to transpile to ES5 compliant JS, consider using a different JS Test Runner than Chutzpah.

NuGet Package Source Blank After VS.NET Update

I recently updated VS.NET 2015 to Update 2 which was just released, but hit a snag with NuGet. Upon opening VS.NET and trying to download NuGet packages, I kept getting errors that the package didn't exist. I noticed the "Package source" dropdown was blank and had no selectable values. Even if I went to the VS.NET options for NuGet, I could no longer see the default nuget.org package source configured. Something must of went awry during the VS.NET update.

Thanks to a nudge from this Connect report, the recommendation was to update the NuGet package manager from the 'Extension and Updates' menu. Sure enough there was an update, and after installing and restarting VS.NET, the "Package source' values were once again populated with nuget.org and I could download packages.