我们有一个多租户ASP.NET应用程序。到目前为止,租户已经相互隔离,但现在我们有代理商管理多个租户,并希望能够通过一个用户帐户管理所有租户。我正在努力找出实现这一目标的最佳方法,希望对我们正在使用的现有技术没有太大的改变。
相关技术细节:
我认为这些要求与SQL Server的安全模型非常相似。我们有一组登录,代表可以登录系统的所有用户。用户应该能够被赋予一个或多个数据库(租户)的角色。示例:用户Bob在公司A中具有管理员角色,但在公司B中只有用户角色。我们公司的员工也有“sysadmin”角色,允许我们访问任何租户以及专门的管理权限,例如创建/删除租户等等。
我已经对各种库,框架等进行了大量研究,但我没有找到任何令人信服的证据证明其他库或框架会比我们现有的更好。所以我现在正在考虑如何让Sql Membership provider做我想做的事情,除非有人能指出我更好的方向。我也不确定我知道在这里搜索的最佳术语。
我正在考虑两个选项:
这些选项中的任何一个都不错吗?或者我应该在别处寻找对此的支持?
答案 0 :(得分:4)
我认为您不会将多租户强加到任何开箱即用的角色提供程序中,因此您可以继续使用SqlMembershipProvider(和SqlRoleProvider)。即使是最新的Microsoft.AspNet.Identity仍然假定用户和角色之间存在多对多的普遍现象。您真正需要的是在该多对多表的主键中添加第3列,该表将标记您的租户,即:
user: 6
role: 4
tenant: 17
user: 6
role: 9
tenant: 18 (and so on)
...通过这种方式,您可以让用户拥有不同租约的不同权限,所有这些都使用相同的角色名称集。
如果您使用选项#2,那么您的[授权]属性将会爆炸。想象一下:
[Authorize(Roles = "TenantA:Admin", "TenantB:Admin", ...)]
public ActionResult Post(int id, SomeViewModel model) {}
...所有这些属性都必须在编译时写入,除非你使用自定义的AuthorizeAttribute,你可以这样做。但即便如此,每次向系统添加租户时,您都会创建一组新的角色,这不是必需的。
答案 1 :(得分:3)
我在一个大型多租户应用程序上工作。我们得出的结论是,每个租户更容易维护单独的数据库,让Web应用程序自动切换数据库上下文,而不是尝试使用过于复杂的数据库模式来为不同的租户建模。
好处
缺点
使用多个数据库实施
我还开发了一个使用单个数据库的多租户应用程序。您很快就会遇到问题,确保您不会跨租户数据。每个查询都需要包含租户ID过滤器。因此,数据库查询总是较慢,尽管您可以索引所有可以尝试的内容并改善情况。
关于成员资格问题,您可以将成员资格架构安装到每个租户数据库中。
什么行不通
理想的替代方案是dynamically switch the ApplicationName,但虽然它似乎有效,ApplicationName is not thread safe,但这不可靠:
因为所有人都使用单个默认成员资格提供程序实例 您可以使用HttpApplication对象提供的请求 多个请求并发执行并尝试设置 ApplicationName属性值。 ApplicationName属性不是 线程可以安全地进行多次写入,并更改ApplicationName 属性值可能导致多个用户的意外行为 一个应用程序。我们建议您避免编写允许的代码 用户设置ApplicationName属性,除非必须。一个例子 可以是设置ApplicationName属性的应用程序 required是管理成员资格数据的管理应用程序 适用于多种应用。这样的应用程序应该是单用户 应用程序,而不是Web应用程序。
替代方案:MembershipReboot
.Net中的多租户很难。使用内置成员身份的开源替代方法是使用由MembershipReboot编写的Brock Allen。它具有一些出色的功能,包括开箱即用的多租户支持:
- 单租户或多租户帐户管理
- 灵活的帐户存储设计(关系/ SQL或对象/ NoSql),使用EF和RavenDB的示例
- 声明感知用户身份
- 支持帐户注册,电子邮件验证,密码重置等。
- 多次登录尝试失败的帐户锁定(密码猜测)
- 电子邮件通知的可扩展模板
- 可自定义的用户名,密码和电子邮件验证
- 帐户活动和更新通知系统(例如审核)
- 帐户与外部身份提供商(企业或社交)的链接
- 支持基于证书的身份验证
- 正确密码存储(通过PBKDF2)
- 可配置的迭代
- 默认为OWASP迭代建议(例如2012年为64K)
- 通过手机短信或客户端证书支持双因素身份验证
醇>最常见的用例是将其集成到ASP.NET或 ASP.NET MVC应用程序,虽然库也可以使用 网络即服务。
替代方案:ServiceStack REST
如果要构建大量使用JavaScript MVC框架(如AngularJS,EmberJS或BackboneJS)的现代Web应用程序,则另一种方法是使用ServiceStack REST服务。 ServiceStack有一个long list of Authentication features,根据我的SS经验,我发现它有一个经过深思熟虑的API模型。