ASP.NET MVC3:我是否需要使用MembershipProvider?

时间:2012-03-13 18:34:55

标签: asp.net-mvc-3 asp.net-membership multi-tenant

我正在使用MVC3构建一个多租户站点。在这个项目之前,我从未接触过.NET堆栈或Web开发,所以你可以想象我的领域知识有点缺乏。

我仍在使用默认的AccountController架构,但我很快就确定我不想使用aspnetdb.mdf进行身份验证,因为它的设计与我的要求完全不同。我确实需要基于角色的身份验证,因此我最终将自定义用户和角色类编写为代码优先的实体类,并使用this tutorial来设置自定义MembershipProvider和RoleProvider。

目前一切正常,但是当我构建多租户功能时,它变得更加混乱。基于this example,我使用Controller的自定义扩展,跟踪哪个租户正在使用此会话,并且我的所有控制器都扩展此类而不是基本Controller类。

所有租户都使用相同的数据库。每个实体都有一个租户属性,用于标识其所属的人。

所以,这就是问题:
用户名不需要全局唯一。只有用户名和租户的组合必须是唯一的。因此,ValidateUser需要知道用户名,密码,和租户。由于我的自定义MembershipProvider不是Controller,因此它不知道哪个租户正在使用该会话,而ValidateUser方法只接受用户名和密码,因此我无法将该信息传递给它。

此外,除了ValidateUser之外,MembershipProvider所做的一切都已经在UserRepository类中实现了,该教程告诉我这个类。我非常喜欢Repository模式,它比遵守MembershipProvider的界面更方便,但现在UserRepository和MembershipProvider之间存在巨大的利益冲突。

所以,我的问题:
我是否需要使用MembershipProvider,甚至是会员资格? 似乎MembershipProvider所做的一切都将由我的存储库类更方便地执行。在这一点上,我所要做的就是编写一个不依赖于Membership的新Authorize属性,一切都应该没有任何MembershipProvider,对吧?如果我不删除会员资格,我不得不完全毁掉我的MembershipProvider实现,以至于它几乎与原始界面不太相似。

......无论是那个还是会员都做了很多我不知道的事情,删除它是公然的愚蠢。这也是一种独特的可能性。

2 个答案:

答案 0 :(得分:4)

不,您不需要使用会员资格,但请考虑一下会员资格。成员资格不涉及您的用户名,地址或其他信息。成员资格与系统的登录帐户严格相关。它仅处理创建,验证,更新或删除登录所需信息的详细信息。就是这样。

同样,角色系统仅为用户分配角色名称。

最终,Membership和Roles只是IPrincipal接口的实现。 FormsAuthentication是IIdentity接口的实现。它们协同工作,以便您可以使用内置的ASP.NET授权和身份验证系统。

会员实际上确实有多个租户的概念。此功能是通过aspnet_users表的“ApplicationNane”字段完成的(也可在Membership类本身中设置)

从会员级别的文档:

  

ApplicationName用于标识特定于应用程序的用户。也就是说,对于指定不同ApplicationName的多个ASP.NET应用程序,数据库中可以存在相同的用户名。这使多个应用程序可以使用同一个数据库来存储用户信息,而不会遇到重复的用户名冲突。或者,多个ASP.NET应用程序可以通过指定相同的ApplicationName来使用相同的用户数据库。 ApplicationName可以在Web应用程序的配置中以编程方式或声明方式设置。

现在,它的设计通常是在Web.Config中设置并在应用程序的生命周期内保持不变,但我认为没有理由不使用它来指定您想要的那个。

这里唯一的问题是Membership.ApplicationName是静态的,这意味着它由App Pool中运行的所有线程共享。但是,如果你在访问它时使用某种锁定,那么这应该不是一个大问题(尽管它可能在某种程度上影响可伸缩性)。

这基本上允许您使用标准的开箱即用会员资格提供程序而无需任何更改。你只需确保保护接入电话。

答案 1 :(得分:1)

您根本不必使用会员提供者。它只是作为一种快速而一致的启动和运行方式提供的。有些人之所以选择它是因为它支持多个数据库(通用成员资格提供程序包括azure以及sql ce,express和full),但是对于其他尝试将其映射到应用程序规则的人来说,可能比它需要的< 5行代码更困难了。验证并签发自己的表单授权凭证。

据说我假设您正在使用表单身份验证。您可以自己发票。我仍然会针对默认MVC模板应该具有的接口进行编程,因此只需添加一个新的租户ID。

话虽如此,我会考虑拥有独特的名字。它确保您不会“忘记”在应用程序中的其他位置执行额外的租户检查,并且tenant1 \ userBip和tenant2 \ userBip令人惊讶地最终会在某些时候踩到彼此的记录。

没错,测试应该发现 - 如果测试完成:)