Recently, I began a new project that was to be built as a Single Page Application or SPA and there are a lot of resources on the web to tell you how to build a SPA in a whole plethora of different technologies on various stacks.
What I wanted to discover though, was how to first deal with authentication within a SPA and later authorization and try as I might, I found next to nothing about this. On top of this, having watched John Papa’s course, Single Page Apps Jumpstart, earlier this year I noticed the discussion board for the course had numerous people asking about authentication and the answer was usually “look at the MS SPA app” but nothing more.
I was surprised at this since at its simplest all the SPA needs to handle is 401- Unauthorized and 403 – Forbidden response codes which is fairly easy to do, the complexity is in the authentication scheme and how it is implemented on the server.
Due to the lack of examples I could find for authentication I have created a GitHub repository to hold samples of authentication from a SPA, over time I hope to increase the number of samples and include other technologies.
A Journey into Authentication
Like most developers creating web applications on the Microsoft stack, my knowledge on authentication & authorization was extremely narrow, generally you used forms auth and relied on the support built into the .NET Framework combined with Membership & Role providers to do the heavy lifting for you, and after having listened to Troy Hunt I knew all too well that what previous experience I had in this area outside forms auth was not sufficient.
Now I was under no illusion I was about to become the next Troy Hunt, but I felt I needed to get a handle on the different authentication schemes that I could use, since the current project had ruled out using OAuth I decided to add it to the list of “must understand later” to save some time.
To start with, I looked at the MS SPA app that people were being directed to and found that it was simple forms authentication with a separate page to handle the login, with authorize attributes on the Web API controllers to “secure” them. One thing about this style of authentication is that if any subsequent authentication is needed, you have to redirect to the login page, if the site doesn’t do it automatically, meaning you either have to code to store state locally or any state the user has will be lost. This then presented nothing new for me to learn and in fact a nasty side effect that would have to be handled, so I moved on.
Since I was going to be using Web API, I started hunting around to find other approaches and first discovered this article by Rick Strahl about using a custom Authorize filter, one of the comments on the article mentioned you shouldn’t use this approach but should use an Action Handler and pointed to this article.
As I wanted more than a cursory understanding of authentication schemes outside of forms authentication, I decided to go back to basics and start at basic authentication.
The basic authentication scheme is where a user’s credentials are sent in a header on every request, specifically the Authorize header, and is simply the username and password separated by a colon and then base64 encoded e.g. bob:password1.
As this is so basic, it is just about a step up from plain text passwords, if you are considering using it (or have to) you should only ever consider using it over https.
There are various authentication schemes that utilise tokens and may be often combined with another form of authentication for making the first request but the response will contain a token generated by the server which is then used on every request that the client makes.
A common format used is Json Web Tokens which is often the default method for a lot of OAuth authentication. The token is built from various pieces of information related to the user and the system being accessed and then encrypted. These tokens may have a long lifespan to prevent the need for users to continually authenticate, e.g., Gmail.
Another token format is HMAC which is used by sites such as Amazon with their web services, during time you are using a service, you will have not one but many tokens since one of the key factors of HMAC is embedding a timestamp and if this timestamp is outside of a specific window the token is considered invalid. HMAC utilises a secret key that is used in the encryption process which is so that you can determine if the data has been tampered with in transmission.
Security Assertion Markup Language is also a token based authentication scheme but differs in that it is XML based and it is signed by a certificate.
I haven’t looked into SAML in any depth as its use was outside of my requirements for the current project but it is on the list to be looked at.
Trying to Use the Various Authentication Schemes
In the repository are examples of each of the different methods of authentication I investigated - forms auth, custom authorize filter, custom message handler & Thinktecture.IdentityModel1. The examples are not supposed to production ready code, they are as simple as possible to purely demonstrate how the authentication occurs to help people follow what is happening and understand how the functionality works.
Going forward, I hope to expand the samples and include OAuth authentication and samples in other web stack technologies such as NancyFx, Simple.Web & Service Stack.
Hopefully this will help other people who are trying to add authentication to there SPA.
(1) I mentioned Thinktecture.IdentityModel which I came across whilst investigating the different schemes, it is an OSS library which handles authentication outside of forms auth on the .NET stack and supports the schemes I outlined above plus a couple more.
It's available as a nuget pkg and is what I have finally settled on using in the project due to the ease of integrating it into the project and the functionality that it offers out of the box.