我正在为几个公司进行相同的项目,因此我们为具有相同数据库结构的不同公司创建了不同的数据库,每个数据库都有自己的标识表,基于角色的菜单,基于角色的访问权限。
我已经编写了一个api来根据提供的用户名连接不同的数据库。因为所有公司都使用相同的登录屏幕登录。
我们通过登录屏幕上传递的用户名来确定要连接的数据库。
示例: 3家公司-abc.com,pqr.com,xyz.com 单一登录屏幕-www.example.com/login 在登录屏幕上,用户将使用其公司电子邮件登录 user @ abc.com,user @ pqr.com,user @ xyz.com
登录后一切正常
问题是: jwt令牌路径始终连接到abc.com数据库,尽管这些记录在其dbs中,但始终会显示user@pqr.com和user@xyz.com的错误消息。
注意 1)将来的公司将会增加,因为这些是我们未来门户数据库的门户的客户-abc.com,bcd.com,def.com .......等。
2)公司所有者可能有多个拥有不同数据库的公司,因此他们需要查看来自两个数据库的报告。 像X先生拥有2家公司(abc.com&pqr.com)一样,尽管公司所有者在不同的数据库中拥有不同的帐户,他可能只需要查看很少的报告就需要两个数据库的数据。
完成此操作后,除以下一项外,所有问题均已解决: 我已替换 // var userManager = context.OwinContext.GetUserManager(); with
var appDbContext =新的ApplicationDbContext(context.UserName); HttpContext.Current.GetOwinContext()。Set(appDbContext); HttpContext.Current.GetOwinContext()。Set(新ApplicationUserManager(新Microsoft.AspNet.Identity.EntityFramework.UserStore(appDbContext)))); var userManager = HttpContext.Current.GetOwinContext()。GetUserManager();
在类中-ApplicationOAuthProvider
我正在寻找让我感到困惑的永久解决方案。 我们非常感谢您的协助。
答案 0 :(得分:0)
是的
1)您应该准备在多个虚拟/物理服务器之间配置信任。这是JWT的主要优点,因为它可以联合。这与Web应用程序之外的数据库无关。如果要为此应用程序使用多个Web服务器,则它们需要彼此信任。
我相信您可以尝试以下方法之一
i)将您的身份验证服务器编码/配置为解决方案中的域/机器可信任
请参阅https://blogs.msdn.microsoft.com/webdev/2017/04/06/jwt-validation-and-authorization-in-asp-net-core/
特别注意“受众”和“授权”字符串,并研究这些概念。
ii)将外部JWT视为适当的“外部”凭证(例如Google OAuth),然后在引用外部令牌后初始化本地JWT或其他安全机制。我将为此找到参考。
2)您应该为每个客户有一个单独的子域(水平规则后,请参见下文)
3)您必须修复初始化数据库上下文的策略。 GetOwinContext方法是IoC模式的糟糕实现。默认的JWT UserManager代码期望db上下文是从OwinContext单例引用派生的。如果要访问多个数据库,这是一个问题。一种方法是现在仅按需构造上下文,然后考虑稍后优化重用和性能的方法。这可能很重要,因为您需要确保它针对任何给定查询都检查正确的数据库。
这里是一个解决方案链接:How to change database name in dbcontext connection string at runtime
4)您的客户需要访问多个数据库。有几种方法可以做到这一点。理想情况下,您将尽可能地维护联盟模式。但是您可能还需要/需要服务器端业务流程:CRUD之外的特殊API,专用于多数据库任务。每个固定报告将有一个服务器端操作。这样的服务器端操作将查看针对数据库查询的请求(就CustomerID而言),它将通过自定义JWT声明(一组CustomerID)来验证访问,如果有任何指定的customerid,则将引发异常不允许。然后,该功能将根据需要使用那些经过验证的客户ID执行。参见[5]如何运行。
以下是一些用于创建自定义JWT声明的链接(这些链接存储在JWT中,通常通过Bearer标头与客户端进行传输):
以下是获取自定义JWT声明的一些链接:
5)对一个联合数据集进行排序是很常见的。这可能是您的情况。如果数据库位于同一RDBMS实例上,则通常可以在一个SQL语句(对于SQL Server)中运行多数据库查询。 (但是,如果您使用的是Azure数据库池,它们通常将(透明地)运行在不同的实例上。我相信最近的更改允许您指定它们在同一实例上,或者现在允许多数据库查询)。否则,服务器端编排意味着您将分别从每个数据库中获得前十名,然后执行最终排序,然后执行前十名将其发送回客户端。最坏的情况是,您需要客户端多次查询,一次针对每个客户ID /数据库,然后在客户端汇总数据。
(我已经讲了很多点,请告诉我您想进一步了解的细节)
我喜欢每个客户的数据库
您似乎正在描述一个系统,其中每个客户都有一个单独的数据库。当您与不需要应用程序内共享数据的客户打交道时,这是我大力提倡的设计。它隔离了数据访问(安全性/隐私性),减少了表锁定争用(性能),并使您可以将数据库移动到其他服务器以实现邻近性和负载平衡(性能)。
all company logins with same login screen.
此要求是您最大的障碍。如果您曾经使用过Slack,您会注意到他们为每个团队设置了一个新的子域。无需每个团队都共享凭据。
这种具有单独子域的设计意味着:
不管您的具体问题有什么答案,我强烈建议您与项目的利益相关者交谈,以查看是否可以实现多个子域设计。
为便于配置(针对Web应用程序),我强烈建议: