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
随机推荐
- 12 postgresql数据库备份和恢复
数据表结构备份与恢复 备份 1.找到postgres 安装目录,在找到bin文件夹,会看到一堆exe后缀的文件,用win+r 打开cmd,将pg_dump.exe 拖进cmd黑窗口中 2.基本语法:- ...
- 8 Oracle语句
1.select name from v$datafile; 用sys方式登陆,查询所有表空间存放的物理路径 2.create tablespace DEMO_TBS datafile 'D:/TBS ...
- ThinkPHP缓存技术(S(),F(),查询缓存,静态缓存)
直接查看原网址 https://blog.csdn.net/u010081689/article/details/47976271
- MySQL数据库(查询语句)
用户 角色 权限 select * from students1:查询这个表里的数据 select ssex from students1:在这个表里面查询ssex(性别) select dist ...
- org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Access denied for user 'root'@'localhost' (using password:
tationProcessor' to allow for resolving potential circular referencesDEBUG 2018-05-28 11:32:35,016 o ...
- python全栈开发 * 10知识点汇总 * 180612
10 函数进阶 知识点汇总 一.动态参数 形参的第三种1.动态接收位置传参 表达:*args (在参数位置编写 * 表⽰接收任意内容) (1)动态位置参数def eat(*args): print(a ...
- stm32f769ni-discovery编译例程需要修改
找不到cmsis_os.h: 方法:在pack文件夹下找cmsis_os.h文件,有四个,选RTOS2文件夹下的. 原因:cmsis_os2.h是新版本,cmsis_os.h封装了cmsis_os2. ...
- mac新手使用
mac新手使用教程 B站上有个Mac云课堂
- PrimeNG之TreeTable
--treetable用于显示分层数据表格的格式 Import import {TreeTableModule,TreeNode,SharedModule} from 'primeng/primeng ...
- Win7升Windows10有获取通知,但是就不推送的解决方法
1. 删除“C:\Windows\SoftwareDistribution\Download”下所有文件2. 以管理员身份运行命令提示符,输入“wuauclt.exe /updatenow”并回车(注 ...