我正在开发一个对几家公司来说相同的项目,所以我们为具有相同数据库结构的不同公司创建了不同的数据库,每个数据库都有自己的身份表,基于角色的菜单,基于角色的访问权限 .
我编写了一个api来根据提供的用户名连接不同的数据库 . 因为所有公司登录都具有相同的登录屏幕 .
我们决定在loginscreen上通过用户名连接哪个数据库 .
Example : 3公司 - abc.com,pqr.com,xyz.com单一登录屏幕 - 登录屏幕上的www.example.com/login用户将使用他们公司的电子邮件用户@ abc.com,user @ pqr.com,user @登录xyz.com
一切都会在登录后运作良好
The problem is: jwt令牌路径始终连接到abc.com数据库,它始终显示user@pqr.com和user@xyz.com的错误消息,尽管这些记录在他们的dbs中 .
Note 1)未来公司将会增加,因为这些是我们门户网站的客户,未来dbs将是 - abc.com,bcd.com,def.com .......等 .
2)公司所有者可能有多个公司也有不同的dbs,因此他们需要查看来自两个dbs的报告 . 就像X先生拥有2家公司(abc.com和pqr.com)一样,他可能需要看到几个需要dbs数据的报告,尽管公司所有者在不同的数据库中拥有不同的账户 .
执行此操作后,所有问题都解决了以下问题:我已经替换了// var userManager = context.OwinContext.GetUserManager();同
var appDbContext = new ApplicationDbContext(context.UserName); HttpContext.Current.GetOwinContext()设置(appDbContext) . HttpContext.Current.GetOwinContext() . Set(new ApplicationUserManager(new Microsoft.AspNet.Identity.EntityFramework.UserStore(appDbContext))); var userManager = HttpContext.Current.GetOwinContext() . GetUserManager();
在课堂上--ApplicationOAuthProvider
注意没有2没有完成 . ## - 任何帮助表示赞赏
我正在寻找永久的解决方案我很困惑 . 任何帮助都非常感谢 .
1 回答
Yes you can
1)您应该准备好跨多个虚拟/物理服务器配置信任 . 这是JWT的主要优势,它可以联合起来 . 这与Web应用程序之外的数据库无关 . 如果您要为此应用程序安装多个Web服务器,则需要相互信任 .
我相信你可以尝试下列之一:
i)将您的身份验证服务器编码/配置为您的解决方案中的域/计算机信任
见https://blogs.msdn.microsoft.com/webdev/2017/04/06/jwt-validation-and-authorization-in-asp-net-core/
特别要注意 Spectator 和权威的字符串,并围绕这些概念进行研究 .
ii)将外部JWT视为适当的“外部”凭证(如Google OAuth),然后在引用外部令牌后初始化本地JWT或其他安全机制 . 我必须找到这方面的参考资料 .
2)您应该为每个客户都有一个单独的子域(在横向规则之后进一步参见下文)
3)您必须修复初始化DB上下文的策略 . GetOwinContext方法是IoC模式的糟糕实现 . 默认的JWT UserManager代码要求db上下文派生自OwinContext单例引用 . 如果您正在访问多个数据库,这是一个问题 . 一种方法是简单地按需构建上下文,并考虑以后优化重用和性能的方法 . 这可能很重要,因为您需要确保为任何给定的查询检查正确的数据库 .
这是一个解决方案链接:How to change database name in dbcontext connection string at runtime
4)您的客户需要访问多个数据库 . 有几种方法可以做到这一点 . 理想情况下,您应尽可能地维护联合模式 . 但是您也可能需要/需要服务器端协调:CRUD之外的专用于多数据库任务的特殊API . 每个固定报告都有一个服务器端操作 . 这样的服务器端操作将查看数据库查询的请求(就CustomerID而言),它将通过自定义JWT声明(一组CustomerID)验证访问,如果任何指定的customerid是,则会抛出异常不允许 . 然后,该函数将根据需要执行那些经过验证的customerid参考 . 有关它如何运行,请参见[5] .
以下是创建自定义JWT声明的一些链接(这些声明存储在JWT中,通过Bearer标头[通常]传输到客户端和从客户端传输):
以下是获取自定义JWT声明的一些链接:
(我已经介绍了很多要点,请告诉我你想要进一步详细说明的内容)
I like database-per-customer
您似乎在描述一个系统,每个客户都有一个单独的数据库 . 当您与没有应用程序需要共享数据的客户打交道时:这是一个我非常倡导的设计 . 它隔离了数据访问(安全/隐私),减少了表锁定争用(性能),并使您能够将数据库移动到不同的服务器以实现接近和负载 balancer (性能) .
all company logins with same login screen.
这个要求是你最大的障碍 . 如果您曾经使用过Slack,您会注意到他们为每个团队设置了一个新的子域 . 每个团队都不需要共享凭据 .
这种具有单独子域的设计意味着:
Web服务器也是一个可移植组件;除了数据库 .
客户可以将自己的DNS记录设置为虚荣URL(即yourapp.acmeco.com);以及您自己的默认子域名(即acmeco.yourapp.com)
无论您的具体问题的答案如何,我强烈建议您与项目的利益相关者交谈,看看是否可以实现多子域设计 .
为了便于配置(请遵循Web应用程序),我强烈建议:
设置通配符DNS记录(我知道这至少支持CloudFlare)
你应该获得一个通配符SSL证书,以便它支付更多的功能,它们是浪费金钱IMO .
配置没有特定主机的Web服务器 . (如果您使用相同的IP配置了其他Web应用程序,则它们仍可以拥有主机名并共享端口80/443) . 使用IIS,这只是意味着将主机URL区域留空 .
您需要应用程序来处理JWT / Session以检查要连接的数据库 . 登录时,您需要检查Host标头以确定要连接的数据库 .