如何使用单独的授权服务器、web api、ui 在 asp.net web 应用程序中组织通信?
How to organize communication in an asp.net web application using separate authorization server, web api, ui?
要求
- 我们有 3 个模块
ui
、api
、IdentityServer
(IS
) (client
、resource
、IS
IdentityServer
)
- 所有模块应该彼此分开(
IS
和 api
的单独数据库)
api
是无状态的(所有需要的身份验证信息都来自令牌)
api
将拥有 \projects
、\users
等资源
- 将来可能会添加另一个入口点,如
another-ui
,它将与 IS
和 api
进行通信,并将拥有自己的声明
问题
主要问题是 api
的资源,如 \projects345
、\users\
、\projects3456\users
等,也可能需要 [=16= 中的声明] ].例如,api
模块读取授权用户的访问令牌并查看等于 ["222", "12345"]
的声明 projects
,因此允许资源 \projects345
或 \projects3456\users
那个用户。
用户同时是IS
中的身份和api
中的资源。项目同时是 IS
中的声明和 api
中的资源。
我想到了通过 id (guid) 记录在两个模块中表示的这些实体。但 id 并不能解决所有问题。
其中一些是:
- 使用其 ID 创建一个新项目应该授予该用户将来使用它的权利,因此我们需要以某种方式保存该用户的声明。模块是分开的,所以我们应该调用
IS
api 来为该用户创建该声明,然后继续进行项目创建。两者(IS
和api
)之间的通信应该如何组织?我们是否需要将 api
注册为 IS
中的另一个客户端?
- 如何更新
IS
中的用户,例如更改电子邮件,phone(可以登录的值)将更新 api
。我想显示警告电子邮件(从令牌中获取)与信息电子邮件不匹配。
请您解释一下现代系统如何处理每个资源访问?
感谢您的宝贵时间。
首先您需要确定什么是索赔。
声明不是权限或角色,它是用户的身份。根据用户的身份,您可以承担权限。
https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims?view=aspnetcore-3.0
A claim is a name value pair that represents what the subject is, not what the subject can do.
因此,从那开始,您可以获得声明并执行以下操作。
假设用户是项目的所有者。创建新项目时,项目 api 可以更新身份服务器并向用户添加声明,说明他是所有者。
在您 api 年代,项目所有者拥有一组权限,并基于这些权限访问特定资源
在 DDD 领域驱动的设计世界中,一点点数据重复并不重要。因此,根据角色(同样,不是 id,而是一个或多个声明到特定角色的映射)复制您的应用程序可能需要的声明并不是一个坏习惯。
当您从 api 更新某种声明时,您应该以交易方式进行。首先考虑一下您是否需要将电子邮件保存在两者中。无论如何,您都会在每次请求时从声明中获取用户数据。它甚至是你需要的东西作为索赔吗?如果没有,仅在您的 api 中。
api 之间的交流以多种方式组织。如果您需要事务或最终一致性,您还应该考虑。与事件或队列通信是微服务的方式,SAGA 等模式是协调器。
要求
- 我们有 3 个模块
ui
、api
、IdentityServer
(IS
) (client
、resource
、IS
IdentityServer
) - 所有模块应该彼此分开(
IS
和api
的单独数据库) api
是无状态的(所有需要的身份验证信息都来自令牌)api
将拥有\projects
、\users
等资源- 将来可能会添加另一个入口点,如
another-ui
,它将与IS
和api
进行通信,并将拥有自己的声明
问题
主要问题是 api
的资源,如 \projects345
、\users\
、\projects3456\users
等,也可能需要 [=16= 中的声明] ].例如,api
模块读取授权用户的访问令牌并查看等于 ["222", "12345"]
的声明 projects
,因此允许资源 \projects345
或 \projects3456\users
那个用户。
用户同时是IS
中的身份和api
中的资源。项目同时是 IS
中的声明和 api
中的资源。
我想到了通过 id (guid) 记录在两个模块中表示的这些实体。但 id 并不能解决所有问题。
其中一些是:
- 使用其 ID 创建一个新项目应该授予该用户将来使用它的权利,因此我们需要以某种方式保存该用户的声明。模块是分开的,所以我们应该调用
IS
api 来为该用户创建该声明,然后继续进行项目创建。两者(IS
和api
)之间的通信应该如何组织?我们是否需要将api
注册为IS
中的另一个客户端? - 如何更新
IS
中的用户,例如更改电子邮件,phone(可以登录的值)将更新api
。我想显示警告电子邮件(从令牌中获取)与信息电子邮件不匹配。
请您解释一下现代系统如何处理每个资源访问?
感谢您的宝贵时间。
首先您需要确定什么是索赔。
声明不是权限或角色,它是用户的身份。根据用户的身份,您可以承担权限。
https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims?view=aspnetcore-3.0
A claim is a name value pair that represents what the subject is, not what the subject can do.
因此,从那开始,您可以获得声明并执行以下操作。
假设用户是项目的所有者。创建新项目时,项目 api 可以更新身份服务器并向用户添加声明,说明他是所有者。
在您 api 年代,项目所有者拥有一组权限,并基于这些权限访问特定资源
在 DDD 领域驱动的设计世界中,一点点数据重复并不重要。因此,根据角色(同样,不是 id,而是一个或多个声明到特定角色的映射)复制您的应用程序可能需要的声明并不是一个坏习惯。
当您从 api 更新某种声明时,您应该以交易方式进行。首先考虑一下您是否需要将电子邮件保存在两者中。无论如何,您都会在每次请求时从声明中获取用户数据。它甚至是你需要的东西作为索赔吗?如果没有,仅在您的 api 中。
api 之间的交流以多种方式组织。如果您需要事务或最终一致性,您还应该考虑。与事件或队列通信是微服务的方式,SAGA 等模式是协调器。