【问题标题】:Duende.IdentityServer v6 > Custom IProfileService implementation does not read IssuedClaims from database after migrating from IdentityServer4Duende.IdentityServer v6 > 从 IdentityServer4 迁移后,自定义 IProfileService 实现不会从数据库中读取 IssuedClaims
【发布时间】:2023-02-20 03:33:53
【问题描述】:

Our web application was using IdentityServer4 (package 2.5.4) and now we migrated to Duende.IdentityServer v6. We have custom IProfileService implementation. The code of client application and ProfileService 100% the same.

In our case, GetProfileDataAsync is called first with ClaimsProviderAccessToken, we create our custom session here and issue two new claims which we add to context.IssuedClaims. They are still saved to database to PersistedGrants table, Data column.

These new claims are still acceccible in client web application, we are good here.

But when it is time to get new access token, IsActiveAsync is called with RefreshTokenValidation and context.Subject does not have these new claims from IssuedClaims anymore.

It works fine in old version, but not in new Duende.IdentityServer v6. Absolutelly not clear what was changes and what direction to use now.

Our goal is to allow one IdentityServer session and several web client sessions. So users can login to IdentityServer once and then reuse this session in different clients without entering login\password.

Simplified code:

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;
        }
    }
  • Could you make it work? if yes, share your solution please
  • No, we changed the flow for now to not use custom claims.

标签: identityserver4 duende-identity-server


【解决方案1】:

这个问题可以追溯到Duende.IdentityServer.ResponseHandling.CreateAccessTokenAsync(花了几个小时调试才弄清楚)。解决方案是在设置context.IssuedClaims 之后更新context.Subject 的声明。对于您的情况,它将是这样的:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    • 2018-03-24
    相关资源
    最近更新 更多