Asp.net core ProfileDataRequestContext.RequestedClaimTypes中缺少子索赔

Asp.net core ProfileDataRequestContext.RequestedClaimTypes中缺少子索赔,asp.net-core,identityserver4,Asp.net Core,Identityserver4,在IdentityServer4中,我定义了一个带有一些声明的IdentityResource: new IdentityResource { Name = "userdata", UserClaims = new List<string> { JwtClaimTypes.Subject, JwtClaimTypes.Role, JwtClaimTypes.Email, JwtClaimTypes.Name } } 在客户端应用程序中,我

在IdentityServer4中,我定义了一个带有一些声明的IdentityResource:

new IdentityResource {
  Name = "userdata",
  UserClaims = new List<string> {
    JwtClaimTypes.Subject,
    JwtClaimTypes.Role,
    JwtClaimTypes.Email,
    JwtClaimTypes.Name
  }
}
在客户端应用程序中,我请求了该范围:

.AddOpenIdConnect("oidc", options => {
  options.Scope.Add("openid");
  options.Scope.Add("userdata");
  options.Scope.Add("offline_access");
  options.Scope.Add("api1");
}
在IS4中,我实现了IProfileService,以向id_令牌添加一些声明

public async Task GetProfileDataAsync(ProfileDataRequestContext context) {

  var sub = context.Subject.GetSubjectId();
  var user = await _userManager.FindByIdAsync(sub);
  if (user == null) {
    throw new ArgumentException("");
  }

  var principal = await _claimsFactory.CreateAsync(user);
  var userClaims = principal.Claims.ToList();

  var claims = new List<Claim> {
    userClaims.Find(x => x.Type == JwtClaimTypes.Subject),
    userClaims.Find(x => x.Type == JwtClaimTypes.Role),
    userClaims.Find(x => x.Type == JwtClaimTypes.Email),
    userClaims.Find(x => x.Type == JwtClaimTypes.Name),
    new Claim("iesseapetenantid", user.TenantId.ToString())
  };

  var requestedClaimTypes = context.RequestedClaimTypes;

  context.AddRequestedClaims(claims);
}
公共异步任务GetProfileDataAsync(ProfileDataRequestContext上下文){ var sub=context.Subject.GetSubjectId(); var user=await\u userManager.FindByIdAsync(sub); if(user==null){ 抛出新的ArgumentException(“”); } var principal=await_claimsFactory.CreateAsync(用户); var userClaims=principal.Claims.ToList(); var索赔=新列表{ userClaims.Find(x=>x.Type==JwtClaimTypes.Subject), userClaims.Find(x=>x.Type==JwtClaimTypes.Role), userClaims.Find(x=>x.Type==JwtClaimTypes.Email), userClaims.Find(x=>x.Type==JwtClaimTypes.Name), 新声明(“iesseapetenantid”,user.TenantId.ToString()) }; var requestedClaimTypes=context.requestedClaimTypes; 上下文。添加请求的索赔(索赔); }
context.AddRequestedClaims(claims)
过滤传递的声明并仅添加客户端请求的声明

问题是在
context.RequestedClaimTypes
中缺少子索赔,但有其他三个:电子邮件、姓名和角色

“次级”索赔为何丢失


谢谢

sub声明是所需的声明,因此它是
StandardScopes.OpenId
的一部分。您不需要另外设置或请求它

var sub=context.Subject.GetSubjectId();
假设
sub
声明已经在上下文中。否则,将引发异常


所有这些都是关于
IdentityResource
id\u令牌的。
ApiResource
token
可以在不引用用户的情况下创建。

是的,我知道了,但问题仍然存在。RequestedClaimTypes不包含子声明,即使我已请求OpenId范围。因此它没有添加到id_token.hmm中,这是两个不同的点:
RequestedClaimTypes
不应包含
sub
,这仅用于其他用户声明。但是令牌必须包括
sub
对不起,我错误地说sub不在id\u令牌中。正如您所说,重要的一点是,
RequestedClaimTypes
仅用于其他用户索赔。这就是我困惑的地方。谢谢。如果您只想添加一些声明,则无需实施IProfileService。看看答案。@RuardvanElburg在我的例子中,我需要实现
IProfileService
,因为我想动态注入一些声明。谢谢
public async Task GetProfileDataAsync(ProfileDataRequestContext context) {

  var sub = context.Subject.GetSubjectId();
  var user = await _userManager.FindByIdAsync(sub);
  if (user == null) {
    throw new ArgumentException("");
  }

  var principal = await _claimsFactory.CreateAsync(user);
  var userClaims = principal.Claims.ToList();

  var claims = new List<Claim> {
    userClaims.Find(x => x.Type == JwtClaimTypes.Subject),
    userClaims.Find(x => x.Type == JwtClaimTypes.Role),
    userClaims.Find(x => x.Type == JwtClaimTypes.Email),
    userClaims.Find(x => x.Type == JwtClaimTypes.Name),
    new Claim("iesseapetenantid", user.TenantId.ToString())
  };

  var requestedClaimTypes = context.RequestedClaimTypes;

  context.AddRequestedClaims(claims);
}