How Identity works in ASP.NET Core

Khanh Nguyen • 8 October 2021 • 

ASP.NET Core.Net CoreIdentity

For everyone that have working with ASP.NET Core for a while, we all know and heard about Identity. As a standardize starting point that was implemented by default, and would work right out the box as needed. But many might want to exploring deeper down that rabbit hole, getting understand how the decision was make, therefore, implement and use other implementation over many storage engine that suit the tastes.

Unfortunately, It's not quite easy finding a place that point out its spirit, but many about how to use and customize it. It's like driving a car without knowing how strong the engine was, keep the same driving mode for city roads and long-steep hill road. Everything would be fine as long as the luck is still with us. But I prefer knowing how to upgrade the tires as it would give much more duration and stable in the long run. Even if I ever need to replace all of them.

So, I would be your tour guide as well as mechanic one today.

Identity with authentication and authorization, do they sticky ?#

Identity#

Identity mechanism was created for manage and storing user accounts in ASP.NET Core apps. Along with some necessary tools that help it achieve the goal right out the box.

What need to be store ? - As Entity Framework Core default implementation.

Authentication and authorization process#

Scratch the surface of Authentication. It was implement as a middleware that handle building HttpContext.User object, that would stick with the entire process of each Http Request. It could verify and build them by many mechanism (even customize), but two widely use was Cookie and Jwt Token.

At the end of this process. We would have access to Request authentication info, such as UserId, Role, Claim,... Which was already store on Identity.

So, after we can access authentication stuff for each http request, determine the user have the right to access corresponding resource became much easier. Role and Claims would mostly suitable for almost every small to medium size projects. And if more specific situation arrive, create more efficient policy as needed, might including further modification of what we need to store, for more convenience guarding resource process.

So, what's the point ?#

Both the two above flow are not coupled together. As long as Identity step provide enough information, being well serve for authentication process.

Therefore, We don't have to use default Identity implementation, as long as it provide enough information satisfied our need. But if there wasn't any specific reason that could lead to that decision. Extend the default implementation would serve really well.

Assembly organization ?#

At first, let explore what's the default assemblies implement at the core of ASP.NET.

Define fundamental building blocks, such as:

Default implementation of all necessary process that won't related to storing process to get Identity works out of the box, such as:

Define default object implementation for storing purpose, such as:

Default implementation of Entity Framework Core for the whole Identity process, which would work with any corresponding Relational database implementation as MySql, MsSql Server, postgresSql,... (remember to install corresponding package):

Implementation of default UI helper, Microsoft.AspNetCore.ApiAuthorization.IdentityServer was implement with IdentityServer4. As a fan of combination between SPA and API, I was not in favor these two, especially IdentityServer4 would be the last version that open source. Which would stick highest with .Net Core 3.1.

What's the idea ?#

Based on how those assemblies was organize, we can have many combinations that suit our taste.

Let's assume we want to take everything as default implementation, simply use Microsoft.AspNetCore.ApiAuthorization.IdentityServer with Microsoft.EntityFrameworkCore.SqlServer would work right out of the box. Storing on Sql Server, ofcourse.

If we want lower level that using our own Front-end ? meet Microsoft.AspNetCore.Identity, Microsoft.AspNetCore.Identity.EntityFrameworkCore and Npgsql.EntityFrameworkCore.PostgreSQL for example.

How about document storage engine ? Microsoft.AspNetCore.Identity with AspNetCore.Identity.MongoDbCore would help.

The whole point that is: Clear seperation out storage mechanisms, UI implementation and facade API usage. That's the power of this design.

But that design came with a price. Every high level API would be scoped and finish their own flow.

Some what disappoint would appear at glance of those relational database lovers. As they are fully compatible with ACID which could execute many operations in a single transaction for fewer database roundtrip, with the same level of data consistence.

But consider the benefit that would bring to all other storage engines doesn't satisfied ACID. Totally acceptable! Ofcourse we can extend our own operation that would take benefit of UnitOfWork concept. But, In my opinion, seems like not worth the benefit of performance that bring.

Conclusion#

I hope this would clear-out the spirit of the design that was choosed, as a default choice of ASP.NET Core framework. Get to know them would give much more freedom, choosing the right tastes for each of our project, regarding what's the size and purpose it is.

More over, ideas can spread, implement our own storage mechanism as needed or even bring them out to other languages are also possible. And most likely, all of them would have the same idea.


Khanh Nguyen

Web developer & .Net lover