贴出主要代码(以下源码的位置位于: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. CPanel/服务器文件及目录

    cPanel服务器默认的各主要目录及配置文件的路径.cPanel服务器很多配置文件的路径和通常情况下安装LAMP的不同,另外还有很多是属于cPanel面板自己的配置文件. 目录 1 Apache 2  ...

  2. word-break和word-wrap的使用和区别

    问题起源: 中文是一个字就是一个单词,而英文字母要有一个空格才将他们分割为一个单词:文字换行没事,主要是英文 <!DOCTYPE html> <html> <head&g ...

  3. #define 宏定义

    gcc Semaphores.c -lpthread --std=c99 1. 边际效应 2. \ 宏定义中一行写不下时,不能换行,必须\+换行 #define CPE_MAIN_PRINTF(fmt ...

  4. 线段树合并 || 树状数组 || 离散化 || BZOJ 4756: [Usaco2017 Jan]Promotion Counting || Luogu P3605 [USACO17JAN]Promotion Counting晋升者计数

    题面:P3605 [USACO17JAN]Promotion Counting晋升者计数 题解:这是一道万能题,树状数组 || 主席树 || 线段树合并 || 莫队套分块 || 线段树 都可以写..记 ...

  5. Eclispe最常用的几个快捷键

    熟练使用快捷键可以在很大程度上提高我们的工作效率,Eclipse的快捷键很多,但是常用的也就那么几个,下面说下Eclispe最常用的几个快捷键: Eclipse的快捷键组合可在Eclipse按下ctr ...

  6. rocketMQ安装部署详细解析

    近来研究了Apache开源项目rocketMQ(原为阿里项目),并在两台linux服务器上完成了部署,现在整理下,供大家参考学习. 一.简介rocketMQRocektMQ是阿里巴巴在2012年开源的 ...

  7. 亿图图示 Edraw Max v9.2 完美破解版

    主程序:http://www.edrawsoft.cn/2download/edrawmax-cn-9.2.exe破解补丁:https://www.lanzous.com/i1fjsyh 密码:52p ...

  8. 更新node的版本,node没有安装到c盘,安装到了D盘

    百度的很久,只有这一个实用,记录一下 https://www.cnblogs.com/xinjie-just/p/7061619.html

  9. Spring Boot 自动配置原理(精髓)

    一.自动配置原理(掌握) SpringBoot启动项目会加载主配置类@SpringBootApplication,开启@EnableAutoConfiguration自动配置功能 @EnableAut ...

  10. Spring Boot 注解配置 day03

    一.SpringBoot注解 @PropertySource 和 @ImportResource和@Bean 1.@PropertySource 加载指定位置的配置文件(只能是properties文件 ...