identityserver4 - IProfileService - 令牌声明
问题描述
我目前正在实施一个 Identity Server 解决方案,我需要一些有关 IProfileService 及其工作原理的帮助。
它公开了一个名为“GetProfileDataAsync”的方法。我知道这是在 IS4 返回令牌时调用的。这意味着该人进入登录屏幕,输入他的详细信息,然后在 IS4 返回身份令牌和访问令牌之前,将调用此方法以添加其他声明。
我目前正在尝试找出实现基于角色和权限的授权的最佳方法。目前,我需要访问用户分配的权限和角色,因为这是我们现有代码所做的,我们只是将身份验证模型切换到 IS4,但保持用户管理与当前相同。
那么问题...
- 我如何最好地实施它?我目前有一个实现 IIdentity 的 ApplicationUser 类。那么我是否应该在其中添加一个角色列表,然后是一个权限列表,然后在用户登录时从数据库中获取它时填充它?
EG 在这种方法中
ApplicationUser user = await _userRepo.FindByUsername(model.Username);
另一种方法是将每个角色和每个权限添加为我的 UserProfileService 中的声明,特别是在下面的方法中
public virtual async Task GetProfileDataAsync(ProfileDataRequestContext context)
我阅读了以下内容
在创建令牌或处理对 userinfo 或自省端点的请求时,IdentityServer 通常需要有关用户的身份信息。默认情况下,IdentityServer 仅具有身份验证 cookie 中的声明以用于此身份数据。将用户所需的所有可能声明放入 cookie 是不切实际的,因此 IdentityServer 定义了一个扩展点,允许根据用户需要动态加载声明。此扩展点是 IProfileService,开发人员通常实现此接口以访问包含用户身份数据的自定义数据库或 API。
在上述情况下,由于我已经实现了 IProfileService,这是否意味着所有加载的声明都将自动返回并放入 Identity/Access 令牌中?这是否意味着对于向 API 发出的每个请求,我的应用程序都将发送一个令牌(在 cookie 中),对于这些包括角色和权限的声明,该令牌可能会变得相当大?IS4网站上的上述声明提到它是不切实际的,有什么替代方法
解决方案
我如何最好地实施它?我目前有一个实现 IIdentity 的 ApplicationUser 类。那么我是否应该在其中添加一个角色列表,然后是一个权限列表,然后在用户登录时从数据库中获取它时填充它?
这里有两种情况,Roles
和Permissions
。Roles
是数据,您可以将它们添加到令牌并传递给客户端和 API。您可以Roles
以任何适合您设计的方式保存数据库。要在令牌中拥有角色,您需要获取它们ProfileService
并添加到令牌中。像这样:
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
context.IssuedClaims.AddRange(context.Subject.Claims);
var user = await _userManager.GetUserAsync(context.Subject);
var roles = await _userManager.GetRolesAsync(user);
foreach (var role in roles)
{
context.IssuedClaims.Add(new Claim(JwtClaimTypes.Role, role));
}
}
完成此操作后,您的令牌应包含角色。确保在https://jwt.ms/上验证令牌
但Permissions
更多的是实时计算。我们需要根据用户信息、用户角色或任何其他可用数据来决定 API 的权限。例如,用户可能具有角色delete
(意味着用户可以删除事物)。如果该用户调用订单 API 并尝试删除其他人的订单,则必须拒绝该订单。意味着删除权限必须根据用户 ID + 用户角色 + 订单所有者 ID 计算。
在上述情况下,由于我已经实现了 IProfileService,这是否意味着所有加载的声明都将自动返回并放入 Identity/Access 令牌中?这是否意味着对于向 API 发出的每个请求,我的应用程序都将发送一个令牌(在 cookie 中),对于这些包括角色和权限的声明,该令牌可能会变得相当大?IS4网站上的上述声明提到它是不切实际的,有什么替代方法
是的,只要 IDS4 需要将有关用户的声明返回给客户端应用程序,就会调用配置文件服务。如果您请求身份和访问令牌 - 它将被调用两次(因为您可能将不同的声明放入每个令牌类型中)。
IS4网站上的上述声明提到它是不切实际的,有什么替代方法
您应该只获取您需要的数据 - 而不是额外的。正如我上面提到的,权限应该即时计算,而不是在令牌中。您也可以在ProfileService
. 但是,如果您使用缓存,则您是负责管理代码的人。
推荐阅读
- python - numpy 向量化回归方法 - 单个独立列 (y) 上的多个相关列 (x)
- .net - 在 cosmos db 中按大小获取文档
- javascript - 自定义反应下拉菜单未正确打开关闭
- python - 结束后在进程中启动的线程会发生什么
- powershell - 如何使用 PowerShell 将模块导入 Azure 自动化帐户?
- git - “repo sync”是否等同于“git remote update && git rebase origin/branch”?
- sql - REGEXP_SUBSTR 将逗号分隔的值拆分为不起作用的行
- java - Selenium,Java - 无法定位元素
- javascript - 在js中,为什么我的文件阅读器在我编辑它时无法跟踪我的输入文件
- mysql - 从多个表中提取数据(mysql)