具有自己的身份表的多数据库应该连接到单个网络 api 并验证 jwt 令牌
multi databases with own identity tables should connect with single web api and validate jwt token
我正在为几家公司开发相同的项目,因此我们为具有相同数据库结构的不同公司创建了不同的数据库,每个数据库都有自己的身份表、基于角色的菜单、基于角色的访问权限。
我写了一个 api 来根据提供的用户名连接不同的数据库。因为所有公司都使用相同的登录屏幕登录。
我们根据登录屏幕上传递的用户名决定连接哪个数据库。
示例:
3 家公司- abc.com、pqr.com、xyz.com
单一登录屏幕 - www.example.com/login
在登录屏幕上,用户将使用他们公司的电子邮件登录
user@abc.com,user@pqr.com,user@xyz.com
登录后一切正常
问题是:
jwt 令牌路径总是连接到 abc.com 数据库,它总是显示 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();
和
var appDbContext = new ApplicationDbContext(context.UserName);
HttpContext.Current.GetOwinContext().Set(appDbContext);
HttpContext.Current.GetOwinContext().Set(new ApplicationUserManager(new Microsoft.AspNet.Identity.EntityFramework.UserStore(appDbContext)));
var userManager= HttpContext.Current.GetOwinContext().GetUserManager();
在 class - ApplicationOAuthProvider
注意 2 没有完成。## - 感谢任何帮助
我正在寻找永久解决方案,我很困惑。
非常感谢任何帮助。
可以
1) 您应该准备好跨多个 virtual/physical 服务器配置信任。这是 JWT 的主要优点,它可以联合。这与 Web 应用程序之外的数据库无关。如果您要为此应用程序使用多个 Web 服务器,则它们需要相互信任。
我相信你可以尝试其中之一:
i) 让您的身份验证服务器 coded/configured 在您的解决方案中被 domains/machines 信任
见https://blogs.msdn.microsoft.com/webdev/2017/04/06/jwt-validation-and-authorization-in-asp-net-core/
特别注意 Audience 和 Authority 字符串,并研究这些概念。
ii) 将外部 JWT 视为适当的 "external" 凭证(如 Google OAuth),然后在引用外部令牌后初始化本地 JWT 或其他安全机制。我必须为此找到参考资料。
2) 您应该为每个客户设置一个单独的 sub-domain(请参阅下面的水平规则)
3) 您必须修复初始化数据库上下文的策略。 GetOwinContext 方法是 IoC 模式的糟糕实现。默认的 JWT UserManager 代码期望数据库上下文从 OwinContext 单例引用派生。如果您正在访问多个数据库,这是一个问题。一种方式是先简单的按需构建上下文,以后再想办法优化复用和性能。这可能很重要,因为您需要确保它为任何给定查询检查正确的数据库。
这是一种解决方案 link:How to change database name in dbcontext connection string at runtime
4) 您的客户需要访问多个数据库。有几种方法可以做到这一点。理想情况下,您尽可能多地维护联合模式。但您也可能 want/need server-side 编排:CRUD 之外的特殊 API,专门用于 multi-db 任务。每个固定报告都会有一个 server-side 操作。这样的 server-side 操作将查看要查询的数据库请求(根据 CustomerID),它将通过自定义 JWT 声明(一组 CustomerID)验证访问,如果有任何指定,它将抛出异常customerids 是不允许的。然后该函数将根据需要执行,并参考那些经过验证的 customerids。请参阅 [5] 以了解它如何 运行。
这里有一些用于创建自定义 JWT 声明的 link(这些声明存储在 JWT 中,通过 Bearer header [通常] 与客户端传输):
以下是获取自定义 JWT 声明的一些 link:
5) 对并集数据进行排序是很常见的。您可能就是这种情况。如果数据库在同一个 RDBMS 实例上,通常可以在一个 SQL 语句中 运行 一个 multi-database 查询(对于 SQL 服务器)。 (但是,如果您使用的是 Azure 数据库池,它们通常 运行 会在不同的实例上(透明地)。我相信最近有一个更改允许您指定它们在同一个实例上,或者他们现在允许 multi-database 查询)。否则,server-side 编排意味着您将从每个数据库分别获得前 10 名,然后执行最终排序并将前 10 名发送回客户端。最坏的情况,您将需要客户端查询多次,每次查询一次 customerid/database,然后在客户端聚合数据。
(我已经涵盖了很多要点,请让我知道您想要进一步了解的细节)
我喜欢database-per-customer
您似乎在描述一个系统,其中每个客户都有一个单独的数据库。当您与不需要 in-app 共享数据的客户打交道时:这是我大力提倡的设计。它隔离数据访问 (security/privacy),减少 table 锁定争用(性能),并使您能够将数据库移动到不同的服务器以实现邻近性和负载平衡(性能)。
all company logins with same login screen.
这个要求是你最大的障碍。如果您曾经使用过 Slack,您会注意到他们为每个团队设置了一个新的子域。每个团队无需共享凭据。
这种具有独立子域的设计意味着:
- web服务器也是一个portable组件;除了数据库。
- 客户可以设置自己的 DNS 记录作为虚荣 URL(即 yourapp.acmeco.com);以及您自己的默认子域(即 acmeco.yourapp.com)
无论您的具体问题的答案如何,我强烈建议您与项目的利益相关者交谈,看看是否可以实现多子域设计。
为了方便配置(遵从网络应用),我强烈推荐:
- 设置通配符 DNS 记录(我知道至少 CloudFlare 支持)
- 您应该获得通配符 SSL 证书,以便轻松加密每个子域。在 1-2 年内,这应该花费您大约 100 美元。不要支付更多的费用在我看来,它们是在浪费金钱。
- 在没有特定主机的情况下配置您的网络服务器。 (如果您有其他 Web 应用程序配置了相同的 IP,它们仍然可以有一个主机名并共享端口 80/443)。对于 IIS,这仅意味着将主机 URL 区域留空。
- 您需要您的应用程序来处理 JWT/Session 以检查要连接到哪个数据库。登录时,您需要检查主机 header 以确定要连接到哪个数据库。
我正在为几家公司开发相同的项目,因此我们为具有相同数据库结构的不同公司创建了不同的数据库,每个数据库都有自己的身份表、基于角色的菜单、基于角色的访问权限。
我写了一个 api 来根据提供的用户名连接不同的数据库。因为所有公司都使用相同的登录屏幕登录。
我们根据登录屏幕上传递的用户名决定连接哪个数据库。
示例: 3 家公司- abc.com、pqr.com、xyz.com 单一登录屏幕 - www.example.com/login 在登录屏幕上,用户将使用他们公司的电子邮件登录 user@abc.com,user@pqr.com,user@xyz.com
登录后一切正常
问题是: jwt 令牌路径总是连接到 abc.com 数据库,它总是显示 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(); 和
var appDbContext = new ApplicationDbContext(context.UserName); HttpContext.Current.GetOwinContext().Set(appDbContext); HttpContext.Current.GetOwinContext().Set(new ApplicationUserManager(new Microsoft.AspNet.Identity.EntityFramework.UserStore(appDbContext))); var userManager= HttpContext.Current.GetOwinContext().GetUserManager();
在 class - ApplicationOAuthProvider
注意 2 没有完成。## - 感谢任何帮助
我正在寻找永久解决方案,我很困惑。 非常感谢任何帮助。
可以
1) 您应该准备好跨多个 virtual/physical 服务器配置信任。这是 JWT 的主要优点,它可以联合。这与 Web 应用程序之外的数据库无关。如果您要为此应用程序使用多个 Web 服务器,则它们需要相互信任。
我相信你可以尝试其中之一:
i) 让您的身份验证服务器 coded/configured 在您的解决方案中被 domains/machines 信任
见https://blogs.msdn.microsoft.com/webdev/2017/04/06/jwt-validation-and-authorization-in-asp-net-core/
特别注意 Audience 和 Authority 字符串,并研究这些概念。
ii) 将外部 JWT 视为适当的 "external" 凭证(如 Google OAuth),然后在引用外部令牌后初始化本地 JWT 或其他安全机制。我必须为此找到参考资料。
2) 您应该为每个客户设置一个单独的 sub-domain(请参阅下面的水平规则)
3) 您必须修复初始化数据库上下文的策略。 GetOwinContext 方法是 IoC 模式的糟糕实现。默认的 JWT UserManager 代码期望数据库上下文从 OwinContext 单例引用派生。如果您正在访问多个数据库,这是一个问题。一种方式是先简单的按需构建上下文,以后再想办法优化复用和性能。这可能很重要,因为您需要确保它为任何给定查询检查正确的数据库。
这是一种解决方案 link:How to change database name in dbcontext connection string at runtime
4) 您的客户需要访问多个数据库。有几种方法可以做到这一点。理想情况下,您尽可能多地维护联合模式。但您也可能 want/need server-side 编排:CRUD 之外的特殊 API,专门用于 multi-db 任务。每个固定报告都会有一个 server-side 操作。这样的 server-side 操作将查看要查询的数据库请求(根据 CustomerID),它将通过自定义 JWT 声明(一组 CustomerID)验证访问,如果有任何指定,它将抛出异常customerids 是不允许的。然后该函数将根据需要执行,并参考那些经过验证的 customerids。请参阅 [5] 以了解它如何 运行。
这里有一些用于创建自定义 JWT 声明的 link(这些声明存储在 JWT 中,通过 Bearer header [通常] 与客户端传输):
以下是获取自定义 JWT 声明的一些 link:
5) 对并集数据进行排序是很常见的。您可能就是这种情况。如果数据库在同一个 RDBMS 实例上,通常可以在一个 SQL 语句中 运行 一个 multi-database 查询(对于 SQL 服务器)。 (但是,如果您使用的是 Azure 数据库池,它们通常 运行 会在不同的实例上(透明地)。我相信最近有一个更改允许您指定它们在同一个实例上,或者他们现在允许 multi-database 查询)。否则,server-side 编排意味着您将从每个数据库分别获得前 10 名,然后执行最终排序并将前 10 名发送回客户端。最坏的情况,您将需要客户端查询多次,每次查询一次 customerid/database,然后在客户端聚合数据。
(我已经涵盖了很多要点,请让我知道您想要进一步了解的细节)
我喜欢database-per-customer
您似乎在描述一个系统,其中每个客户都有一个单独的数据库。当您与不需要 in-app 共享数据的客户打交道时:这是我大力提倡的设计。它隔离数据访问 (security/privacy),减少 table 锁定争用(性能),并使您能够将数据库移动到不同的服务器以实现邻近性和负载平衡(性能)。
all company logins with same login screen.
这个要求是你最大的障碍。如果您曾经使用过 Slack,您会注意到他们为每个团队设置了一个新的子域。每个团队无需共享凭据。
这种具有独立子域的设计意味着:
- web服务器也是一个portable组件;除了数据库。
- 客户可以设置自己的 DNS 记录作为虚荣 URL(即 yourapp.acmeco.com);以及您自己的默认子域(即 acmeco.yourapp.com)
无论您的具体问题的答案如何,我强烈建议您与项目的利益相关者交谈,看看是否可以实现多子域设计。
为了方便配置(遵从网络应用),我强烈推荐:
- 设置通配符 DNS 记录(我知道至少 CloudFlare 支持)
- 您应该获得通配符 SSL 证书,以便轻松加密每个子域。在 1-2 年内,这应该花费您大约 100 美元。不要支付更多的费用在我看来,它们是在浪费金钱。
- 在没有特定主机的情况下配置您的网络服务器。 (如果您有其他 Web 应用程序配置了相同的 IP,它们仍然可以有一个主机名并共享端口 80/443)。对于 IIS,这仅意味着将主机 URL 区域留空。
- 您需要您的应用程序来处理 JWT/Session 以检查要连接到哪个数据库。登录时,您需要检查主机 header 以确定要连接到哪个数据库。