Duende.IdentityServer v6 > 从 IdentityServer4 迁移后,自定义 IProfileService 实现不会从数据库中读取 IssuedClaims

问题描述 投票:0回答:1

我们的 Web 应用程序使用的是 IdentityServer4(包 2.5.4),现在我们迁移到了 Duende.IdentityServer v6。我们有自定义 IProfileService 实现。客户端应用程序和 ProfileService 的代码 100% 相同

在我们的例子中,首先使用 ClaimsProviderAccessToken 调用 GetProfileDataAsync,我们在这里创建自定义会话并发出两个新的声明,我们将其添加到 context.IssuedClaims。它们仍然保存到数据库中的 PersistedGrants 表,数据列。

这些新声明在客户端 Web 应用程序中仍然可以访问,我们在这里很好。

但是当需要获取新的访问令牌时,会使用 RefreshTokenValidation 和上下文调用 IsActiveAsync。Subject 不再具有来自 IssuedClaims 的这些新声明。

它在旧版本中工作正常,但在新的 Duende.IdentityServer v6 中不行。绝对不清楚发生了什么变化以及现在使用什么方向。

我们的目标是允许一个 IdentityServer 会话和多个 Web 客户端会话。因此用户可以登录到 IdentityServer 一次,然后在不同的客户端中重复使用这个会话,而无需输入登录名\密码。

简化代码:

public class CustomClaimService : IProfileService
{
    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var claimsToIssue = new List<Claim>();
        switch (context.Caller)
        {
            case IdentityServerConstants.ProfileDataCallers.ClaimsProviderAccessToken:
                context.IssuedClaims.Add(new Claim(ClaimTypes.TestClaim, "TestClaimValue"));
                break;
        }
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        switch (context.Caller)
        {
            case IdentityServerConstants.ProfileIsActiveCallers.RefreshTokenValidation:
                var encryptedClaim = context.Subject?.Claims?.FirstOrDefault(c => c.Type == ClaimTypes.TestClaim); // ALWAYS NULL
                context.IsActive = encryptedClaim != null;
                break;
        }
    }
identityserver4 duende-identity-server
1个回答
0
投票

问题可以追溯到

Duende.IdentityServer.ResponseHandling.CreateAccessTokenAsync
(调试了好几个小时才弄明白)。解决方案是在设置
context.Subject
之后更新
Identity
的声明(通过
context.Subject.Claims
,因为
context.IssuedClaims
是只读的)。对于您的情况,它将是这样的:

context.IssuedClaims.Add(new Claim(ClaimTypes.TestClaim, "TestClaimValue"));

ClaimsIdentity identity = (ClaimsIdentity)context.Subject.Identity;

if (!identity.Claims.Any(claim => claim.Type == ClaimTypes.TestClaim))
{
    identity.AddClaim(new Claim(ClaimTypes.TestClaim, "TestClaimValue"));
}

现在,当刷新令牌时,

context.Subject.Claims
将包含您的
TestClaim

© www.soinside.com 2019 - 2024. All rights reserved.