• IdentityServer4中AccessToken和IdentityToken中包含的Claims构成


    贴出主要代码(以下源码的位置位于:IdentityServer4.Services.DefaultClaimsService)

            /// <summary>
            /// Returns claims for an identity token
            /// </summary>
            /// <param name="subject">The subject</param>
            /// <param name="resources">The requested resources</param>
            /// <param name="includeAllIdentityClaims">Specifies if all claims should be included in the token, or if the userinfo endpoint can be used to retrieve them</param>
            /// <param name="request">The raw request</param>
            /// <returns>
            /// Claims for the identity token
            /// </returns>
            public virtual async Task<IEnumerable<Claim>> GetIdentityTokenClaimsAsync(ClaimsPrincipal subject, Resources resources, bool includeAllIdentityClaims, ValidatedRequest request)
            {
                Logger.LogDebug("Getting claims for identity token for subject: {subject} and client: {clientId}",
                    subject.GetSubjectId(),
                    request.Client.ClientId);
    
                var outputClaims = new List<Claim>(GetStandardSubjectClaims(subject));
                outputClaims.AddRange(GetOptionalClaims(subject));
    
                // fetch all identity claims that need to go into the id token
                if (includeAllIdentityClaims || request.Client.AlwaysIncludeUserClaimsInIdToken)
                {
                    var additionalClaimTypes = new List<string>();
    
                    foreach (var identityResource in resources.IdentityResources)
                    {
                        foreach (var userClaim in identityResource.UserClaims)
                        {
                            additionalClaimTypes.Add(userClaim);
                        }
                    }
    
                    // filter so we don't ask for claim types that we will eventually filter out
                    additionalClaimTypes = FilterRequestedClaimTypes(additionalClaimTypes).ToList();
    
                    var context = new ProfileDataRequestContext(
                        subject,
                        request.Client,
                        IdentityServerConstants.ProfileDataCallers.ClaimsProviderIdentityToken,
                        additionalClaimTypes);
    
                    await Profile.GetProfileDataAsync(context);
    
                    var claims = FilterProtocolClaims(context.IssuedClaims);
                    if (claims != null)
                    {
                        outputClaims.AddRange(claims);
                    }
                }
                else
                {
                    Logger.LogDebug("In addition to an id_token, an access_token was requested. No claims other than sub are included in the id_token. To obtain more user claims, either use the user info endpoint or set AlwaysIncludeUserClaimsInIdToken on the client configuration.");
                }
    
                return outputClaims;
            }
    
            /// <summary>
            /// Returns claims for an identity token.
            /// </summary>
            /// <param name="subject">The subject.</param>
            /// <param name="resources">The requested resources</param>
            /// <param name="request">The raw request.</param>
            /// <returns>
            /// Claims for the access token
            /// </returns>
            public virtual async Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(ClaimsPrincipal subject, Resources resources, ValidatedRequest request)
            {
                Logger.LogDebug("Getting claims for access token for client: {clientId}", request.Client.ClientId);
    
                // add client_id
                var outputClaims = new List<Claim>
                {
                    new Claim(JwtClaimTypes.ClientId, request.Client.ClientId)
                };
    
                // check for client claims
                if (request.ClientClaims != null && request.ClientClaims.Any())
                {
                    if (subject == null || request.Client.AlwaysSendClientClaims)
                    {
                        foreach (var claim in request.ClientClaims)
                        {
                            var claimType = claim.Type;
    
                            if (request.Client.PrefixClientClaims)
                            {
                                claimType = "client_" + claimType;
                            }
    
                            outputClaims.Add(new Claim(claimType, claim.Value, claim.ValueType));
                        }
                    }
                }
    
                // add scopes
                foreach (var scope in resources.IdentityResources)
                {
                    outputClaims.Add(new Claim(JwtClaimTypes.Scope, scope.Name));
                }
                foreach (var scope in resources.ApiResources.SelectMany(x => x.Scopes))
                {
                    outputClaims.Add(new Claim(JwtClaimTypes.Scope, scope.Name));
                }
    
                // a user is involved
                if (subject != null)
                {
                    if (resources.OfflineAccess)
                    {
                        outputClaims.Add(new Claim(JwtClaimTypes.Scope, IdentityServerConstants.StandardScopes.OfflineAccess));
                    }
    
                    Logger.LogDebug("Getting claims for access token for subject: {subject}", subject.GetSubjectId());
    
                    outputClaims.AddRange(GetStandardSubjectClaims(subject));
                    outputClaims.AddRange(GetOptionalClaims(subject));
    
                    // fetch all resource claims that need to go into the access token
                    var additionalClaimTypes = new List<string>();
                    foreach (var api in resources.ApiResources)
                    {
                        // add claims configured on api resource
                        if (api.UserClaims != null)
                        {
                            foreach (var claim in api.UserClaims)
                            {
                                additionalClaimTypes.Add(claim);
                            }
                        }
    
                        // add claims configured on scope
                        foreach (var scope in api.Scopes)
                        {
                            if (scope.UserClaims != null)
                            {
                                foreach (var claim in scope.UserClaims)
                                {
                                    additionalClaimTypes.Add(claim);
                                }
                            }
                        }
                    }
    
                    // filter so we don't ask for claim types that we will eventually filter out
                    additionalClaimTypes = FilterRequestedClaimTypes(additionalClaimTypes).ToList();
    
                    var context = new ProfileDataRequestContext(
                        subject,
                        request.Client,
                        IdentityServerConstants.ProfileDataCallers.ClaimsProviderAccessToken,
                        additionalClaimTypes.Distinct());
    
                    await Profile.GetProfileDataAsync(context);
    
                    var claims = FilterProtocolClaims(context.IssuedClaims);
                    if (claims != null)
                    {
                        outputClaims.AddRange(claims);
                    }
                }
    
                return outputClaims;
            }
    

      

    简易总结:


    AccessToken
    从ApiResource中的UserClaims和Scopes.UserClaims中提取返回的Claims类型,构建一个上下文,再调用Profile.GetProfileDataAsync()获取,根据上面提取的Claims类型限制最终返回的Claims

    IdentityToken
    从IdentityResource的UserClaims中提取返回的Claims类型,构建一个上下文,再调用Profile.GetProfileDataAsync()获取,根据上面提取的Claims类型限制最终返回的Claims
    在IdentityResource.UserClaims中设置的内容需要将Client.AlwaysIncludeUserClaimsInIdToken设置为true

    GetIdentityTokenClaimsAsync的includeAllIdentityClaims参数只有在只请求IdToken的时候会被设置成true,
    官方解释:if no access token is requested, then we need to include all the claims in the id token

  • 相关阅读:
    配置centOS下的Python
    linux基础命令2
    linux基础命令1
    linux常用命令(运维用到)
    Lab 10-2
    Lab 10-1
    Lab 9-3
    archlinux 装完系统连接 wifi 网络
    arch Linux(二)
    arch Linux 安装完,无法通过 SSH 远程连接 root 用户问题
  • 原文地址:https://www.cnblogs.com/myesn/p/AccessIdentityToken_Claims.html
Copyright © 2020-2023  润新知