Skip to main content

Part 1 of customizing the ASP .Net MVC identity membership provider using Entity Framework

By default ASP .Net MVC allows developers to customize the way the framework handles user membership. Back in the old days when people used ASP .Net Webforms the main way to do this was to implement a custom membership provider.

ASP .Net MVC introduced a new way to do this, using a series of interfaces. In the old way of doing things, a developer had to implement a single abstract class called "MembershipProvider". The new approach pretty much split up this big class into multiple simpler interfaces each providing a part of the functionality of the whole membership system. It is called Identity. It also introduced better support for 3rd party authentication using external systems such as Facebook, Twitter and so on.

It is actually built over the old membership system and is available in ASP .Net Core too but it might differ in some ways.

The most important interfaces are:
  • IQueryableUserStore and IUserStore, which store the users registered on the website, including their password if available
  • IUserRoleStore, which stores the roles on the website and the what users belong to them
  • IUserLoginStore, which stores external logins such as Facebook, LinkedIn and so on

They are actually part of the repository pattern implementation. Each of them stores and handles separately some of the entities involved in ASP .Net membership such as the roles, users and profiles. Pretty much all of them have to be implemented in order for the membership system to work properly. In general, they implement CRUD operations. They also have special generic parameters, TUser and TKey. TUser represents the user entity type used by the framework and TKey represents the type of the unique ID of each user stored in the database. Their only real usage is to specify what kind of key type to use in order to identify each entity stored in these repositories. The key type can be for example long or string.

This is how the IUserStore interface looks like and methods it exposes:



The methods exposed in these need to the implemented in a class which will be a concrete implementation of the interface. Unfortunately, the  ASP .Net framework doesn't use these interfaces directly which makes things a bit more complicated. For this, there exists another class called UserManager which brings together all of these interfaces and uses the functionality exposed by them.

But here there is a bad design choice. The UserManager class takes just a class which implements IUserStore as a parameter. You can't pass all the other interfaces. It expects all of the interfaces mentioned above to be implemented by a single class and pass that as a parameter to the UserManager class. This class should be derived from which makes things even more complicated. Again a bad design choice here. It should also provide a static method to create instances of this clas like bellow:




So a big, unified interface should be made which includes all of the interfaces as shown below:



Because of the reason mentioned above, a single big class needs to be made to implement the big interface and all the repositories or "stores" for the membership functionality implicitly.

After this, all of these classes need to be registered somehow in the framework in order to be used by them. Unfortunately, there is bad design choice again here. All of these components have to be registered in the system in different and sometimes obscure ways.

The class which implements the repositories has to be registered using dependency injection. In the example below NInject was used but anything works here:




This has to be done just once at application startup. There are a lot of ways to achieve this like using Global.asax.cs. Another way would be using the startup attribute OwinStartupAttribute on classes which specify methods to be executed before the website starts. Having so many ways to do the same thing seems like a bad design choice to me.

The UserManager class has to be registered differently because it needs a special kind of life cycle as in the example below:




Only the first line of code in method contained in the example above registers the actual user manager. The rest of the code configures user authentication. It just tells the system to use a method ApplicationUserManager.Create that creates and returns instances of the user manager. The method can be found in an example above which contains the code for the actual user manager. Again, this needlessly complicated and a bad design choice. The only way to register this is using the
OwinStartupAttribute because it needs an IAppBuilder instance to register the user manager. This seems like a really bad idea to me because it doesn't use the standard dependency injection mechanism. I like software to be uniform because it is much more easier to understand.

Once they are registered in the system, they can be used by controllers which require membership functionality. They can use membership in various ways. For example, a controller depends on the membership functionality just by using the Authorize attribute on a controller action or on a controller itself in case it needs to restrict access only to logged in users or to users in specific roles.

Or a controller can use membership directly using the UserManager class or a derived class from it like in the example bellow:




In the example above, the big class which implements CRUD operations for membership entities is automatically passed to the constructor through dependency injection. The UserManager can be passed both through standard dependency injection or through another weird mechanism based on OWIN context which isn't the focus of this post.

The second part of this tutorial will become available later. A working example of an ASP .Net MVC website used in this post which uses customized membership can be found here: https://github.com/Alecu100/NetBazaar

Comments

Popular posts from this blog

Some software development common sense ideas

 I haven't really written here in a long time so it's time to write some new things. These are just some random common sense things that seemed to short to write about individually but seem really interesting and useful to me or other people 1. There is nothing fixed in software development, all things vary by circumstances and time Remember the documentation that didn't seem that important when you started the project, well after a couple of years one the application has grown and become really complicated, no one actually knows everything about the application anymore. So now you really need that documentation. What happens if you suddenly need much more people to develop the application because of some explosive growth? Without documentation, new developers will just look at the application like they look at a painting. This actually happened to me. Maybe in the beginning of a project, a technology really helped you a lot but as the project grew, it started making things

My thoughts as an experienced developer in this field.

To be honest, I would have never guessed that      I would end up saying these these things, especially jn the beginning of my career. As you become more experienced, you kind of get to see everything and you become less impressed by new things. Honestly there is some sort of repetitiveness in this field and we kind of like to reinvent the wheel quite often, because well, we become a bit too easily bored. Take for example how the web looks now, a lot of it has been borrowed from other places, mostly desktop development, especially the parts about making custom reusable components.  Or from older frameworks, like state management in the UI which actually was first properly implemented in Asp .Net Webforms, as far as I know, something like 20 years ago, where you used to have the dreaded view state.  But most likely something similar existed before that too. I was not that surprised when React adopted initially this idea. Or even less surprised when hooks where introduced that seemed a b

Some things which are often blindly applied and followed by developers which are not always good

This is probably one of the most controversial things that I have written so far but I am just tired of hearing about these things and discussing these things. Other developers that I know share part of my feelings. I would rather hear more about how people built things, overcame challenges or what new interesting ideas and concepts they implemented. Those things are really interesting and innovative, not hearing about the same theoretical things over and over again. I can just read and learn those things from 100 sources on the internet. Firstly, one of the most discussed and promoted things is agile/scrum development. I think I have been through 5-8 workshops about agile development methodology. And each time, some things differed. There is no 100% standard approach to this. Everyone uses their own version of this development methodology and seem to argue a lot that their approach is right and everyone else is doing it wrong. You go to an interview, this will be one of the first 10 t