首页 文章

具有自己的身份表的多个数据库应该与单个web api连接并验证jwt令牌

提问于
浏览
2

我正在开发一个对几家公司来说相同的项目,所以我们为具有相同数据库结构的不同公司创建了不同的数据库,每个数据库都有自己的身份表,基于角色的菜单,基于角色的访问权限 .

我编写了一个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 回答

  • 0

    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声明的一些链接:

    • Get custom claims from a JWT using Owin5)对一组联合数据进行排序是很常见的 . 这可能是你的情况 . 如果数据库位于同一个RDBMS实例上,则通常可以在一个SQL语句(对于SQL Server)中运行多数据库查询 . (但是,如果您使用的是Azure数据库池,它们通常会在不同的实例上运行(透明地) . 我相信最近有一个更改可以让您指定它们位于同一个实例上,或者它们现在允许多数据库查询) . 否则,服务器端业务流程意味着您将分别从每个数据库获得前10名,然后执行最终排序,并将前10名发送回客户端 . 最糟糕的情况是,您需要客户端多次查询,每个客户端/数据库一次,然后在客户端聚合数据 .

    (我已经介绍了很多要点,请告诉我你想要进一步详细说明的内容)


    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标头以确定要连接的数据库 .

相关问题