ASP.NET MVC3: do I need to use Provider membership?

I am building a multi-tenant site with MVC3. Prior to this project, I never touched the .NET stack or the web development in general, as you can imagine that I don't have enough domain knowledge.

I still use the default AccountController system by default, but I quickly decided that I did not want to use aspnetdb.mdf for authentication, as its design is very different from my requirements. I need role-based authentication, so I ended up writing the User and Role user classes as Entity class classes and used this tutorial to configure custom MembersProvider and RoleProvider.

Everything is working fine now, but as I create feature-rich features, it becomes more messy. Based on in this example , I use a custom controller extension that keeps track of which tenant is using this session, and all my controllers extend this class instead of the base class of the controller.

All tenants use the same database. Each object has a Tenant property that identifies to whom it belongs.

So here is the problem:
Usernames do not have to be globally unique. Only a combination of username and tenant should be unique. Therefore, ValidateUser needs to know the username, password and tenant. Since my user MembershipProvider is not a controller, it does not know which tenant is using the session, and the ValidateUser method only accepts a username and password, so I cannot pass this information to it.

In addition, almost everything that is part of the MembershipProvider, in addition to ValidateUser, is already implemented in the UserRepository class, which this tutorial told me about. I prefer the repository template, and this is more convenient than sticking to the MembershipProvider interface, but now there is a serious conflict of interest between UserRepository and MembershipProvider.

So my question is:
Do I need to use MembershipProvider or even membership? It seems that all MembershipProvider members will be executed more conveniently using my repository class. At this point, I still have to write a new Authorize attribute that does not rely on membership, and everything should work without any MembershipProvider element, right? If I do not lose my membership, I am forced to completely cripple my MembershipProvider implementation to such an extent that it still does not look like the original interface.

... Either this or membership does a ton of things that I don’t know about, and removing them is blatant stupidity. This is also a great opportunity.

+4
source share
2 answers

You do not have to use a membership provider. It was simply provided as a quick and consistent way to get up and work. Some people choose it because it supports several databases (universal membership providers include azure, as well as sql ce, express and full), but for others trying to match it with your application rules, it can be more difficult than 5 lines of code required for authentication and issuing custom auth ticket forms.

With that said, I assume that you are using forms authentication. You can simply issue a ticket yourself. I would still program against the interface for this, which should have a default MVC pattern, so just add a new tenant id.

With that said, I would name unique names. This ensures that you will not β€œforget” to do an additional tenant check somewhere else in the application, and tenant1 \ userBip and tenant2 \ userBip will surprisingly eventually stomp on each other.

True, testing should reveal this - if testing is completed :)

+1
source

No, you do not need to use membership, but think for a moment what membership is. Membership is not related to your usernames, addresses or other information. Membership is strictly related to an account in the system. It processes details only when creating, checking, updating or deleting information necessary for entering the system. What is it.

Similarly, a role system only assigns a role name to a user.

Ultimately, membership and roles are just an implementation of the IPrincipal interface. Although FormsAuthentication is an implementation of the IIdentity interface. They work together so you can use ASP.NET's built-in authorization and authentication system.

The participant does have the concept of multiple tennants. This functionality is performed through the ApplicationNane field of the aspnet_users table (also set in the Membership class itself)

From the documentation for the Membership class:

The application name is used to identify application-specific users. That is, the same username can exist in the database for several ASP.NET applications that specify a different application name. This allows multiple applications to use the same database to store user information without conflicts of duplicate user names. Alternatively, multiple ASP.NET applications can use the same user database by specifying the same ApplicationName. ApplicationName can be set programmatically or declaratively in the configuration for the web application.

Now it is usually installed in Web.Config and remains unchanged for the life of the application, but I see no reason why you cannot use it to indicate which tenant you want.

The only problem here is that Membership.ApplicationName is static, which means that it is used by all threads running in the application pool. However, if you use some kind of lock to access it, then this should not be a huge problem (although this can affect scalability at some level).

This will allow you to use the standard inbox membership provider without any changes. You simply do not have to protect access calls.

+4
source

Source: https://habr.com/ru/post/1401226/


All Articles