贴出主要代码(以下源码的位置位于: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

IdentityServer4中AccessToken和IdentityToken中包含的Claims构成的更多相关文章

  1. 判断DataTale中判断某个字段中包含某个数据

    // <summary> /// 判断DataTale中判断某个字段中包含某个数据 /// </summary> /// <param name="dt&quo ...

  2. 转载:C++中两个类中互相包含对方对象的指针问题

    原文链接:http://www.cnblogs.com/hanxi/archive/2012/07/25/2608068.html 前几天很不爽,因为C++中两个类中互相包含对方对象的指针编译时提示某 ...

  3. 多态时最好将基类的析构函数设为virtual、 C++中两个类相互包含引用问题 (转载)

    多态:http://blog.csdn.net/tmljs1988/article/details/8146521 C++中两个类相互包含引用问题:http://blog.csdn.net/leo11 ...

  4. struts 2中为什么抽象包不能包含action?

    struts 2中为什么抽象包不能包含action?麻烦写详细点!

  5. sql中同一个Trigger里同时包含Insert,Update,Delete

    sql中同一个Trigger里同时包含Insert,Update,Delete SQLServer是靠Inserted表和Deleted表来处理的,判断一下就可以了,只不过比ORACLE麻烦一点 cr ...

  6. IdentityServer4在Asp.Net Core中的应用(三)

    今天的内容是授权模式中的简化模式,还是先看以下授权流程图: 在这种模式中我们将与OpenID结合使用,所以首先我们要了解OpenID和OAuth的区别,关于他们的区别,在我上一篇博客<理解Ope ...

  7. OpenCV - Android Studio 中集成Opencv环境(包含opencv_contrib部分)

    我在上一篇博客中说到了在Android中集成OpenCV,但是那个版本的OpenCV是没有SIFT和SURF算法的,因为这些算法是受专利保护的,所以并没有被包含在预编译库中,所以如果想要使用SIFT和 ...

  8. C++中两个类相互包含引用问题

    在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A { int i; B b; } class B { in ...

  9. Java中list集合ArrayList 中contains包含的使用

    Java中list集合ArrayList 中contains包含的使用 https://blog.csdn.net/qq_38556611/article/details/78774690

随机推荐

  1. 移动端如何用swiper实现导航栏效果

    在移动端如何用swiper实现导航栏效果 我们在写移动端的时候会有滑动和点击导航后滑动到目标页面功能:而这个功能如果自己写的话会很麻烦,所以我在这推荐一下swiper这个插件. 其实swiper中的官 ...

  2. 三、CSS语言

    CSS语言 1.概述:CSS (Cascading Style Sheets)是层叠样式表用来定义网页的显示效果.可以解决html代码对样式定义的重复,提高了后期样式代码的可维护性,并增强了网页的显示 ...

  3. vue的事件对象,方法执行

    方法都写在methods重,有两种写法:1. getMsg:function(){ alert(); },  这种写法就是对象中的方法 2. getMsg1(){ alert(); }注意没有func ...

  4. opencart3如何安装模板

    opencart 3模板采用twig模式,安装模板也有点不大一样,随ytkah一起来看看opencart3如何安装模板吧1.下载模板文件,用ftp上传到对应的位置,一般有几个文件夹,比如:admin. ...

  5. 【UML】-NO.45.EBook.5.UML.1.005-【UML 大战需求分析】- 通讯图(Communication Diagram)

    1.0.0 Summary Tittle:[UML]-NO.45.EBook.1.UML.1.005-[UML 大战需求分析]- 通讯图(Conmunication Diagram) Style:De ...

  6. 七、UIViewController导航栏

    概述 上一节我们算是跟UIViewController打了个招呼,同时也表示我们正式介入iOS开发.本节我们将介绍UI界面的一个常用元素:导航栏. iOS为UIViewController提供了内置导 ...

  7. Python基础(九) type元类

    python元类:type()    元类是python高阶语法. 合理的使用可以减少大量重复性的代码. 元类实际上做了以下三方面的工作: 干涉创建类的过程 修改类 返回修改之后的类 为什么使用元类? ...

  8. Unity之显示fps功能

    如下: using UnityEngine; using System.Collections; public class ShowFpsOnGUI : MonoBehaviour { public ...

  9. Django框架详细介绍---ORM相关操作---select_related和prefetch_related函数对 QuerySet 查询的优化

    Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化 引言 在数据库存在外键的其情况下,使用select_related()和pre ...

  10. python split()函数的用法

    转自: https://blog.csdn.net/orangefly0214/article/details/80810449 函数:split() Python中有split()和os.path. ...