architecture - 将用户数据存储在身份验证服务器或资源服务器中?或两者?
问题描述
这是我第一次使用 IdentityServer 4 和 AspNetIdentity 设置 OpenID Connect,我希望有人可以揭开关于存储用户数据的部分的神秘面纱。
到目前为止我读到的是用户数据应该存储在连接到身份验证服务器的身份验证数据库中,但我真的很想将用户数据存储在连接到资源服务器的资源数据库中。
我目前有一个如下所示的数据模型:
我省略了 User 和 Event 的许多字段,但希望您能明白这一点。我们有一个用户表、一个事件表和一个主机表。用户可以主持活动。User 和 Event 之间的多对多关系是通过 Host 表实现的。
这是一个关于架构的基本问题,但真的很难找到一个有意义的好答案,而且这不是一个完全的hack。到目前为止,我已经阅读了来自不同人的以下解决方案:
仅将所有用户数据存储在 Auth db 中,然后在 Auth 服务器上设置 API,以便资源服务器可以从 Auth 服务器获取数据。
其他人说,用户所在城市或国家/地区等与身份验证无关的数据不应存储在身份验证数据库中。而是仅将身份验证相关数据保留在身份验证服务器中,并将任何与用户相关的数据保留在资源数据库中。这听起来像两个用户记录需要同步?听起来是个坏主意。
让 Resource server 和 Auth server 成为一个应用程序,这样我们就可以在 User、Host 和 Event 之间建立必要的关系。但这似乎违背了使用 OpenID Connect 的全部目的。
那么这里的标准架构是什么?或者,如果没有万能的,您将如何存储这些用户数据?
解决方案
考虑到关注点的分离和单一的责任:
不只有一个用户表。表中的字段仅在上下文中有意义。
用户可以有一个谷歌帐户登录,但对于不是您可以联系员工的帐户的企业。以及如何在不属于上下文的报告中显示信息?假设您将 city 存储在身份上下文中。那么您将如何在报告中显示该信息?您将需要业务环境中的信息。
还要考虑身份上下文是否是存储信息的好地方。因为用户处于控制之中。如果用户不同意使用这些信息,或者只是删除了帐户,会发生什么?当您想同步数据时使用什么策略?
共享上下文是不行的。身份是 IdentityServer 的职责,身份上下文应该只包含关于身份的信息,并且只能由 IdentityServer 访问。请注意,IdentityServer 不绑定到一个应用程序。
在每个上下文中都需要一个用户表。信息可能看起来是多余的,但实际上并非如此,因为它是单独上下文的一部分。就像您使用 google 之类的提供商登录时一样。然后在身份上下文中创建用户的本地副本。
但也许您不应该在业务上下文中将其称为用户。因为在业务上下文中没有用户。他们很可能是员工、客户等。他们可以登录,但不一定。并且可能有(身份)对业务不了解的用户(例如,在多个应用程序的情况下)。
IdentityServer 是对用户进行身份验证的权限。授权可以在多个级别上实施。您可以创建一个单独的授权服务器(如policyserver)。或更低级别(基于资源),其中“人员”表中存在用户意味着用户可以访问资源。
单独上下文最好的部分是在上下文中您可以创建表之间的关系,而不会干扰其他上下文。如果您愿意,可以轻松切换到不同的 oidc 提供程序。但是一旦你开始混合上下文,就没有回头路了。
在 oidc 中非常有用的一件事是sub
声明。只需通过声明查找用户sub
并将本地 ID 用于业务上下文。
关于字段city
和country
身份上下文:有多个级别的身份验证,因此您实际上可能需要此上下文中的信息。但是,如果您需要其他上下文中的信息(例如,在报告中显示),那么它应该被添加到那里(以及)。
推荐阅读
- ruby-on-rails - 如何在 Rails 视图中调用 javascript 函数?
- testing - Gatling,测试并发问题
- angular - 使用响应式表单设计复杂的 UI Angular 8
- html - 如何获取某个类之前的 HTML 元素?
- kubernetes - 如何在大使 api 网关中禁用 openapi docs API 调用?
- hl7-fhir - 急于加载以供参考
- javascript - 如何将 python 正则表达式转换为 js 正则表达式?
- android - 如何在 android studio 中集成 Python OpenCV 代码
- python - 在同一 x 轴上绘制时间序列的每一年
- php - 有人知道为什么图片没有上传吗