将用户数据存储在 auth server 或 resource server 中?或两者?
Store user data in auth server or resource server? Or both?
这是我第一次使用 IdentityServer 4 和 AspNetIdentity 设置 OpenID Connect,我希望有人能揭开有关存储用户数据的部分的神秘面纱。
到目前为止我读到的是用户数据应该存储在连接到 auth 服务器的 Auth 数据库中,但我真的很想将用户数据存储在连接到的资源数据库中资源服务器。
我目前的数据模型如下所示:
我省略了 User 和 Event 的许多字段,但希望您能理解。
我们有一个用户 table、一个事件 table 和一个主持人 table。用户可以主持活动。用户和事件之间的多对多关系是通过主机 table.
这是一个关于体系结构的基本问题,但很难找到一个有意义的好答案,而且这不是一个完全的黑客。到目前为止,我已经从不同的人那里了解到以下解决方案:
仅将所有用户数据存储在 Auth 数据库中,然后在 Auth 服务器上设置一个 API,以便 Resource 服务器可以从 Auth 服务器获取数据。
其他人说,与身份验证无关的数据(例如用户的城市或国家/地区)不应存储在身份验证数据库中。取而代之的是仅将与身份验证相关的数据保留在身份验证服务器中,并将任何与用户相关的数据保留在资源数据库中。这听起来像是两个用户记录需要同步?听起来是个坏主意。
让资源服务器和授权服务器成为一个应用程序,这样我们就可以在用户、主机和事件之间建立必要的关系。但这似乎违背了使用 OpenID Connect 的全部目的。
那么这里的标准架构是什么?或者,如果没有放之四海而皆准的方案,您将如何存储这些用户数据?
当我遇到类似问题时,我个人更喜欢使用的一个额外选项是在各种应用程序之间简单地共享身份数据库。这解决了不必要的重复问题。但是,如果你这样做,你需要尝试确保维护某种关注点分离——身份管理不是由资源服务器应用程序完成的,同样资源相关的数据管理也不是由身份验证应用程序完成的。
考虑到关注点分离和单一责任:
不只有一个用户 table。 table 中的字段仅在上下文中有意义。
用户可以有一个 google 帐户来登录,但对于不是您可以联系到员工的帐户的企业。如何在不属于上下文的报告中显示信息?假设您将城市存储在身份上下文中。那么您将如何在报告中显示该信息?您将需要业务环境中的信息。
还要考虑身份上下文是否是存储信息的好地方。因为用户在控制之中。如果用户不同意使用这些信息,或者干脆删除帐户,会发生什么情况?当你想同步数据时使用什么策略?
共享上下文是不行的。身份是IdentityServer的责任,身份上下文应该只包含关于身份的信息,并且只能被IdentityServer访问。请注意,IdentityServer 未绑定到一个应用程序。
您在每个上下文中都需要一个用户 table。 信息可能看起来多余但实际上并非如此,因为它是单独上下文的一部分。就像您使用 google 这样的提供商登录时一样。然后在身份上下文中创建用户的本地副本。
但也许您不应该在业务上下文中将其称为用户。因为在业务上下文中没有用户。他们很可能是员工、客户等。他们可以登录,但不一定。并且可能有业务不了解的(身份)用户(例如,在多个应用程序的情况下)。
IdentityServer是对用户进行身份验证的权限。授权可以在多个级别上实施。您可以创建一个单独的授权服务器(如 policyserver). Or lower level (resource-based),其中 'person' table 中存在用户意味着该用户可以访问该资源。
独立上下文的最佳部分是,您可以在上下文中创建 table 之间的关系,而不会干扰其他上下文。如果愿意,您可以轻松切换到不同的 oidc 提供商。但是一旦你开始混合上下文,就没有回头路了。
oidc 中非常有用的一件事是 sub
声明。只需通过 sub
声明查找用户并使用业务上下文的本地 ID。
关于身份上下文中的字段 city
和 country
:存在多个级别的身份验证,因此您可能实际上需要此上下文中的信息。但是,如果您需要其他上下文中的信息(例如在报告中显示),那么也应该将其添加到那里。
这是我第一次使用 IdentityServer 4 和 AspNetIdentity 设置 OpenID Connect,我希望有人能揭开有关存储用户数据的部分的神秘面纱。
到目前为止我读到的是用户数据应该存储在连接到 auth 服务器的 Auth 数据库中,但我真的很想将用户数据存储在连接到的资源数据库中资源服务器。
我目前的数据模型如下所示:
我省略了 User 和 Event 的许多字段,但希望您能理解。 我们有一个用户 table、一个事件 table 和一个主持人 table。用户可以主持活动。用户和事件之间的多对多关系是通过主机 table.
这是一个关于体系结构的基本问题,但很难找到一个有意义的好答案,而且这不是一个完全的黑客。到目前为止,我已经从不同的人那里了解到以下解决方案:
仅将所有用户数据存储在 Auth 数据库中,然后在 Auth 服务器上设置一个 API,以便 Resource 服务器可以从 Auth 服务器获取数据。
其他人说,与身份验证无关的数据(例如用户的城市或国家/地区)不应存储在身份验证数据库中。取而代之的是仅将与身份验证相关的数据保留在身份验证服务器中,并将任何与用户相关的数据保留在资源数据库中。这听起来像是两个用户记录需要同步?听起来是个坏主意。
让资源服务器和授权服务器成为一个应用程序,这样我们就可以在用户、主机和事件之间建立必要的关系。但这似乎违背了使用 OpenID Connect 的全部目的。
那么这里的标准架构是什么?或者,如果没有放之四海而皆准的方案,您将如何存储这些用户数据?
当我遇到类似问题时,我个人更喜欢使用的一个额外选项是在各种应用程序之间简单地共享身份数据库。这解决了不必要的重复问题。但是,如果你这样做,你需要尝试确保维护某种关注点分离——身份管理不是由资源服务器应用程序完成的,同样资源相关的数据管理也不是由身份验证应用程序完成的。
考虑到关注点分离和单一责任:
不只有一个用户 table。 table 中的字段仅在上下文中有意义。
用户可以有一个 google 帐户来登录,但对于不是您可以联系到员工的帐户的企业。如何在不属于上下文的报告中显示信息?假设您将城市存储在身份上下文中。那么您将如何在报告中显示该信息?您将需要业务环境中的信息。
还要考虑身份上下文是否是存储信息的好地方。因为用户在控制之中。如果用户不同意使用这些信息,或者干脆删除帐户,会发生什么情况?当你想同步数据时使用什么策略?
共享上下文是不行的。身份是IdentityServer的责任,身份上下文应该只包含关于身份的信息,并且只能被IdentityServer访问。请注意,IdentityServer 未绑定到一个应用程序。
您在每个上下文中都需要一个用户 table。 信息可能看起来多余但实际上并非如此,因为它是单独上下文的一部分。就像您使用 google 这样的提供商登录时一样。然后在身份上下文中创建用户的本地副本。
但也许您不应该在业务上下文中将其称为用户。因为在业务上下文中没有用户。他们很可能是员工、客户等。他们可以登录,但不一定。并且可能有业务不了解的(身份)用户(例如,在多个应用程序的情况下)。
IdentityServer是对用户进行身份验证的权限。授权可以在多个级别上实施。您可以创建一个单独的授权服务器(如 policyserver). Or lower level (resource-based),其中 'person' table 中存在用户意味着该用户可以访问该资源。
独立上下文的最佳部分是,您可以在上下文中创建 table 之间的关系,而不会干扰其他上下文。如果愿意,您可以轻松切换到不同的 oidc 提供商。但是一旦你开始混合上下文,就没有回头路了。
oidc 中非常有用的一件事是 sub
声明。只需通过 sub
声明查找用户并使用业务上下文的本地 ID。
关于身份上下文中的字段 city
和 country
:存在多个级别的身份验证,因此您可能实际上需要此上下文中的信息。但是,如果您需要其他上下文中的信息(例如在报告中显示),那么也应该将其添加到那里。