ASP.NET Core: Supporting multiple Authorization, route branching
By: Maarten Merken
Tags: Microsoft, Aspnetcore, Routing, Mvc, Dotnet Core

Each branch will have its own MVC pipeline and its own authentication mechanism. They both share the same codebase, but different configuration.

What is the benefit of this?

The benefit of this setup is that both branches (/api1 and /api2) receive their own IOC container and therefore each branch can handle their own kind of authentication. The use cases for this can vary, you could handle multiple tenants using route branching, multiple environments with different implementation. You could, perhaps, build your own API gateway using this technique.

Let’s see how this is done effectively, let’s start by adding the controllers:

We want both controllers to be authorized using the same Authorization Policy (MyDbPolicy) that only requires an authenticated user.

However, we’ll need to support two ways of authenticating, either using the MyDb1 authentication database or using the MyDb2 database.

Please note that these can be two entirely different authentication mechanisms, I’m omitting a lot of plumbing by simple authenticating against a database in plain text, I hope you get the idea.

To solve this issue, I suggest to branch the application into two branches, one with MyDb1 authentication and the other with MyDb2 authentication, both using the same authorization policy, as a result, the API’s will authenticate against their own predefined database, but executing the same business logic code. This way, the logic will be unaware of the authentication mechanism. All that’s required is any authenticated user to run the controller logic.

To setup ASP.NET Core pipeline branching, you’ll need to install the WebApiContrib.Core nuget package first: https://www.nuget.org/packages/WebApiContrib.Core/

After the installation, we’ll split the pipeline using the UseBranchWithServices extension method from the package, our Startup file should look like this:

Since we’re not doing anything related to MVC in the ConfigureServices and Configure methods, the application will respond with “Branches configured!” when browsing to the root /.

This makes sense, since the pipeline has not been configured to use MVC, it is only in the branches that MVC is setup.

A fully working solution is available through a GitHub branch.

After cloning this repo, please check out branch origin/route-branching-separation to see the fully working solution.

git checkout -b route-branching-separation origin/ route-branching-separation

Before running the repo, make sure to have two local databases running first (MyDb1 and MyDb2). Run the SQL\create_auth_table.sql script for each database to ensure the Authentication table on both databases.

After the application is up and running, open postman to test both API’s.

These are the results for /api1:

The following are the results for /api2:

As you see, two different routes using different authentication methods. The pipeline split into two entirely different branches.

We could go even further and separate the controllers entirely to only be visible to a specific branch.

The diagram below describes what we will achieve next, the /api1 branch will host the users API, the /api2 branch will host the data API. Both branches will be hosting the common API. But only the branch-specific API’s will be exposed by their respected branch. Navigating to /api2/users will result in a 404.