How to build middleware for next level authentication in Episerver

casper.rasmussen/ September 16, 2016/ Episerver CMS, Episerver Commerce/ 2 comments

Episerver continuously improves all aspects of our platform. One area that definitely – and unfortunately – lacks attention, for native support, is the authentication part, which out of the box relies on the old ASP.NET Membership framework.
Let me be honest, I don’t like ASP.NET Membership. ASP.NET Identity and the OWIN specification, via Katana, is, in my humble opinion, the way to go regarding identity management and I am very pleased to see the countless examples of how OWIN and ASP.NET Identity is leveraged through the Episerver community.

In order to maximize your value of reading this post, I recommend you to have a fundamental understanding of the objective behind the OWIN specification and also some level of familiarity with the Katana implementation.

Let me start with a statement; Katana is for more than authentication against common identity providers such as Facebook. Individuals working on enterprise solutions tend to agree. They recognize the need for challenging an identity provider – e.g. via OAuth2.0 – that goes beyond what’s already provided by the community supporting the Katana project. Indeed, there are a multitude of options, but you will, at some point, be required to define a custom authentication middleware that’s tailored to the clients implementation of a recognized authentication protocols such as Auth2.0.

Create custom OAuth Middleware for an OWIN powered Episerver solution

Let’s start with a small recap of the OAuth2.0 protocol. It allows users to prove their identity, when using a web platform, without having to provide credentials. Users – e.g. site administrators – can use the the site without worrying about their credentials being compromised. At a very high level, the protocol is based on a authorization server (here after referred to as identity provider) issuing access tokens that is used to grant access to resources – such as profile information – via a resource server. What we are about to build is the authentication mechanism in the third party application recognized as the client.

That authentication mechanism is Middleware. Middleware are modules written to work with Katana. It’s executed at a low level, as part of the OWIN pipeline, and are used to respond to HTTP requests.

An example of Middleware is the code that provides authenticating against Facebook. Most people recognizes it via it’s registration:

Each authentication Middleware provides an abstraction for providning middleware options – it’s flexibility – and registration in the OWIN pipeline. The UseFacebookAuthentication extension is syntactic candy designed to provide an easy setup.

Let’s investigate what’s inside Use[YourAuthProvider]Authentication to prepare you for a customized implementation

The OAuth Process

Managing a challenge against a OAuth Identity Provider requires several interactions with the browser, the middleware and the identity provider. It’s all managed via HTTP requests and would, in the good old IE6 days (with refresh sounds), play a symphony of clicking sounds.

It mainly consists of these 5 steps:

  1. A HTTP request that requires authentication is caught by Middleware due to HTTP 401 response
  2. End users browser is redirected to identity provider
  3. User provides credentials or accepts the information claimed by client application
  4. Identity provider redirects back to client application and the incoming request is caught by Middleware
  5. The application builds an external Claims Identity that can be used to create an user profile and login

Creating a custom authentication mechanism, via Middleware, requires us to manage all the subprocesses in above steps.

The process begins when Episerver requires a user to authenticate – e.g. due to access control list or an MVC [Authorize] attribute. Our client application can, when authentication is required, redirect the user to a login page outlining the options for providing an identity.

When the user clicks on an option – e.g. “Sign in with Loyalty Account”, the client application will request a authentication challenge to the provider type “LoyaltyProgramIdp”, through the OwinContex, followed by a HTTP 401. At this point, the ApplyResponseChallengeAsync method is invoked in the Middleware, with the matching provider type, and it can intercept the response to redirect to appropriate authorize endpoint.

Once the user has reached the identity provider, outside of our Episerver application, he/she will be prompted to provide credentials (as an example to provide his/her identity). When the user finishes, the identity provider will redirect the browser to the applications callback path that were detailed by the Middleware. The callback path is a reserved path, such as /signin-loyaltyprogramidp, and is a path used by the Middleware to identify a request coming back from a third party service. Please remember, that the middleware is invoked before Episerver routing occurs.
So, as soon as the request reaches the client application, the Middleware will, if the callback path is correct, intercept the request. Intercept happens because it has to build an user identity. Valuable information, being especially the authorization code (often referred to as code), has been forwarded with the request. Immediately after obtaining the authorization code, the Middleware will, via AuthenticateAsync, contact the identity providers token-endpoint to request an access token.

When the Middleware is in possession of the access token, the resource server can be requested to retrieve necessary information about the user. A Claims Identity can be constructed as soon as the user’s information has been collected. This Claims Identity can, after a internal redirect to an application controller – e.g. /login/callback, be used to create an user profile and login.

Combine this with the inner parts defining a Middleware

Middleware consists of several parts that manages the sub processes outlined above. Below elements – mainly classes – are used to register the Middleware and handle all authentication requests.

AuthenticationExtensions
Similar to the UseFacebookAuthentication, an authentication extensions is used to abstract the registration of Middleware. A static class named LoyaltyProgramAuthenticationExtensions would be the obvious for our example. It’s intended to extend the IAppBuilder by providing a UseLoyaltyProgramAuthentication method.

AuthenticationOptions
LoyaltyProgramAuthenticationOptions details the flexbility in the Middleware. It exposes configuration options that affects the authentication process. LoyaltyProgramAuthenticationOptions has to inherits from AuthenticationOptions and often provides these basic configuration options:

  1. ClientId
  2. ClientSecret
  3. Authority: endpoint for identity provider that often varies across environments
  4. Scope: user information – e.g. email and profile – client requests access too
  5. Provider: provider enabling developer to intercept callback and authentication flows
  6. CallbackPath: reserved path that triggers Middleware authentication

Please be aware that the provider type, being “LoyaltyProgramIdp”, is set as part of the base class constructor.

AuthenticationMiddleware
The LoyaltyProgramAuthenticationMiddleware is rather sparse. It mainly registers the the LoyaltyProgramAuthenticationHandler.

AuthenticationHandler
The LoyaltyProgramAuthenticationHandler is responsible for the largest part of the authentication process. It inherits from AuthenticationHandler<LoyaltyProgramAuthenticationOptions> and often requires three methods:

  1. ApplyResponseChallengeAsync: manages the redirect when client application requests a challenge against identity provider.
  2. InvokeAsync: manages the callback, by checking if path matches /signin-loyaltyprogramidp, and requests authentication
  3. AuthenticateCoreAsync: authenticates user based on authorization code issued by identity provider

AuthenticationProvider
LoyaltyProgramAuthenticationProvider specifies delegates that are called during challenge and authentication:

  1. Authenticated: is invoked when a user is successfully authenticated and is often used to add additional claims.
  2. ReturnEndPoint: is invoked after the ClaimsIdentity is constructed and before it’s signed in.

Understanding the processes and elements involved in authentication using Middleware is a prerequisite when building custom Middleware for any OAuth2.0 identity provider. Examples of a large variety of identity providers can be accessed via the OwinOAuthProviders Github project.

Happy authenticating!

2 Comments

  1. Interesting post, although I\’m curious as to how Episerver relies on forms authentication \’out of the box\’? It\’s true that the Admin mode user creation only works with older providers, but that\’s really only a helper. And the Alloy Technologies site isn\’t Episerver \’out the box\’… it\’s just a sample site. There\’s lots of things not implemented in that! Bear in mind that Episerver is a framework that fully supports OWIN/WSFederation etc. and has done for a long time. You can see articles on Episerver world over 18 months ago that detail it. In reality, when you create a new Episerver site it\’s up to you what you use… old style providers, OWIN, whatever.(And, as an interesting aside, the Quicksilver Episerver Commerce reference site uses OWIN).Anyway, this isn\’t negating your post or anything and maybe I\’ve missed something – I\’m just wondering what your perspective is on what Episerver is \’out the box\’ 🙂

  2. Hi Dan.

    Thanks for adding your perspective. I am fully aware of Alloy and that it is not reflecting ‘out of the box’.

    Episerver does support OWIN – correct.. but there are still some fundamental issues that developers has to work around to make it function as expected with ASP.NET Identity. Top of mind, these can for instance be:
    1. All Commerce and CMS preferences, for Editors and Administrators, are bound to profile providers and ASP.NET Membership
    2. Commerce Migrations – specifically the redirect to the login page – relies on Forms Authentication and will not work if this is deactivated.

    In my opinion, we are 95% there..

    I am, in above post, acknowledging that the Episerver Community numerous times has proven OWIN can function. In my opinion, it would be a shame to create a long blog post about Katana Middleware if it weren’t possible to utilize in our context.

    Have a great day.

    Casper Aagaard Rasmussen

Leave a Comment

Your email address will not be published. Required fields are marked *

Please type the characters of this captcha image in the input box

Please type the characters of this captcha image in the input box
You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
*
*