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
IdentityServer4中AccessToken和IdentityToken中包含的Claims构成的更多相关文章
- 判断DataTale中判断某个字段中包含某个数据
// <summary> /// 判断DataTale中判断某个字段中包含某个数据 /// </summary> /// <param name="dt&quo ...
- 转载:C++中两个类中互相包含对方对象的指针问题
原文链接:http://www.cnblogs.com/hanxi/archive/2012/07/25/2608068.html 前几天很不爽,因为C++中两个类中互相包含对方对象的指针编译时提示某 ...
- 多态时最好将基类的析构函数设为virtual、 C++中两个类相互包含引用问题 (转载)
多态:http://blog.csdn.net/tmljs1988/article/details/8146521 C++中两个类相互包含引用问题:http://blog.csdn.net/leo11 ...
- struts 2中为什么抽象包不能包含action?
struts 2中为什么抽象包不能包含action?麻烦写详细点!
- sql中同一个Trigger里同时包含Insert,Update,Delete
sql中同一个Trigger里同时包含Insert,Update,Delete SQLServer是靠Inserted表和Deleted表来处理的,判断一下就可以了,只不过比ORACLE麻烦一点 cr ...
- IdentityServer4在Asp.Net Core中的应用(三)
今天的内容是授权模式中的简化模式,还是先看以下授权流程图: 在这种模式中我们将与OpenID结合使用,所以首先我们要了解OpenID和OAuth的区别,关于他们的区别,在我上一篇博客<理解Ope ...
- OpenCV - Android Studio 中集成Opencv环境(包含opencv_contrib部分)
我在上一篇博客中说到了在Android中集成OpenCV,但是那个版本的OpenCV是没有SIFT和SURF算法的,因为这些算法是受专利保护的,所以并没有被包含在预编译库中,所以如果想要使用SIFT和 ...
- C++中两个类相互包含引用问题
在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A { int i; B b; } class B { in ...
- Java中list集合ArrayList 中contains包含的使用
Java中list集合ArrayList 中contains包含的使用 https://blog.csdn.net/qq_38556611/article/details/78774690
随机推荐
- vue的数据绑定和组件化
组件:就是自定义标签, 也是Vue的实例对象; 组件好处:就像工作分工,函数封装等 组件分为全局组件和局部组件: 全局组件,在Vue身上的组件,所有的vue挂载的元素内都可以使用:正是因为这一点,co ...
- [No0000D1]WPF—TreeView无限极绑定集合形成树结构
1.如图所示:绑定树效果图 2.前台Xaml代码: <Window x:Class="WpfTest.MainWindow" xmlns="http://schem ...
- [No000018D]Vim快速注释/取消注释多行的几种方法-Vim使用技巧(2)
在使用Vim进行编程时,经常遇到需要快速注释或取消注释多行代码的场景,Vim教程网根据已有的教程介绍,总结了三种快速注释/取消注释多行代码的方法. 一.使用Vim可视化模式快速注释/取消注释多行 在V ...
- centos7忘记root密码重置
1.重启服务器,选择内存按“e”编辑 2.找到下入内容 3.将上图中标记的ro改为rw init=/sysroot/bin/sh 4.按Ctrl+x进入单用户模式 5.执行命令chroot /sysr ...
- python摸爬滚打之day21---- 模块
1.MD5加密模块 MD5是一种不可逆的加密算法, 是安全而且可靠的. 在某些网站上能够搜到MD5解密工具, 其实并没有解密工具, 而是"撞库"的方式. 网站将一些MD5数据保存 ...
- 如何使用Windows防火墙禁止软件联网
很多软件需要联网,当我们为了“某些目的”,不想让软件联网的时候,我们有没有办法做到呢?答案是肯定的,那就是使用Windows系统自带的防火墙来屏蔽软件的联网,禁止软件出站请求,这样就可以了,下面介绍具 ...
- js数组代码库
1 数组操作 1.1 数组去重:ES6的方法 //ES6新增的Set数据结构,类似于数组,但是里面的元素都是唯一的 ,其构造函数可以接受一个数组作为参数 //let arr=[1,2,1,2,6,3, ...
- 20190412 T-SQL语言二
Use xsxk;WITH c_count(id,xb,rs)AS (SELECT 班级,性别,count(*)FROM XS GROUP BY 班级,性别 ) SELECT * FROM c_cou ...
- grunt 打包 分解(并非原创)
1. require('time-grunt')(grunt); Time how long tasks take. Can help when optimizing build times任务执行时 ...
- java开发定时任务执行时间
定时任务执行时间配置详解 Seconds Minutes Hours Day-of-month Month Day-of-Week Year 秒 分 时 天 ...