IProfileService - 令牌中的声明

IProfileService - Claims in tokens

我目前正在实施一个 Identity Server 解决方案,我需要一些关于 IProfileService 及其工作原理的帮助。

它公开了一个名为“GetProfileDataAsync”的方法。据我所知,这是在 IS4 returns 时调用的一个令牌。这意味着此人进入登录屏幕,输入他的详细信息,然后在 IS4 returns 身份令牌和访问令牌之前,将调用此方法以添加其他声明。

我目前正在尝试找出实现基于角色和权限的授权的最佳方式。目前我需要访问用户分配的权限和角色,因为这是我们现有代码所做的,我们只是将我们的身份验证模型切换到 IS4,但保持用户管理不变。

然后问题...

  1. 我如何最好地实施它?我目前有一个实现 IIdentity 的 ApplicationUser class。那么我应该在其中添加一个角色列表,然后是一个权限列表,然后在用户登录时从数据库中获取它时填充它吗?

在这个方法中 ApplicationUser user = await _userRepo.FindByUsername(model.Username);

另一种方法是在我的 UserProfileService 中添加每个角色和每个权限作为声明,特别是在下面的方法中
public virtual async Task GetProfileDataAsync(ProfileDataRequestContext context)

  1. 我阅读了以下内容

    Often IdentityServer requires identity information about users when creating tokens or when handling requests to the userinfo or introspection endpoints. By default, IdentityServer only has the claims in the authentication cookie to draw upon for this identity data. It is impractical to put all of the possible claims needed for users into the cookie, so IdentityServer defines an extensibility point for allowing claims to be dynamically loaded as needed for a user. This extensibility point is the IProfileService and it is common for a developer to implement this interface to access a custom database or API that contains the identity data for users.

出现上述情况,我已经实现了IProfileService,是不是意味着加载的所有声明都会自动返回并放入Identity/Access令牌中?这是否意味着对于向 API 发出的每个请求,我的应用程序都将发送一个令牌(在 cookie 中),对于这些包含角色和权限的声明,该令牌可能会变得相当大? IS4 网站的上述声明提到它是不切实际的,有什么替代方案

How best do I implement it? I currently have an ApplicationUser class which implements IIdentity. So should I add a list of roles in there and then a list of permissions, and then populate it when I go get it from the DB when the user does a LogIn?

这里有两种东西,RolesPermissionsRoles 是数据,您可以将它们添加到令牌并传递给客户端和 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更多的是实时计算things.We需要根据用户信息、用户角色或任何其他可用数据来决定API的权限。 例如,用户可能具有 delete 的角色(意味着用户可以删除内容)。如果此用户调用订单 API 并试图删除其他人的订单,则该订单必须被拒绝。意味着删除权限必须根据用户 ID + 用户角色 + 订单所有者 ID 计算。

With the above situation, as I have implement the IProfileService, does that mean that all claims that are loaded will be automatically returned and put into the Identity/Access token? Does that mean that for every request that is made to the API, my application will be sending in a token (in the cookie) which could get quite big with these claims that include roles and permissions? What is the alternative as the above statement from the IS4 website mentions it is impractical

是的,每当 IDS4 需要 return 向客户端应用程序声明用户时,就会调用配置文件服务。如果您请求身份和访问令牌 - 它将被调用两次(因为您可能对每种令牌类型提出不同的声明)。

What is the alternative as the above statement from the IS4 website mentions it is impractical

你应该只获取你需要的数据——而不是额外的。正如我上面提到的,权限应该即时计算,而不是在令牌中。 您也可以在 ProfileService 中使用缓存。但是如果你使用缓存,你就是负责在你的代码中管理的人。