Oauth 2.0 “中未返回自定义资源/索赔”;用户信息“;

Oauth 2.0 “中未返回自定义资源/索赔”;用户信息“;,oauth-2.0,identityserver4,openid-connect,Oauth 2.0,Identityserver4,Openid Connect,我试图将一些自定义声明添加到IdentityServer4流中,但无法使它们显示在/userinfo端点中 我现在只使用“内存中”配置,因此在这里,我用我的自定义范围创建了一个新的IdentityResource: 新标识资源{ DisplayName=“我的自定义资源”, Name=“mycustom”, UserClaims=新列表{ “mycustom.myvalue” } } 我已将我的客户设置为能够使用此功能: 新客户端{ 允许范围={ IdentityServerConstants

我试图将一些自定义声明添加到IdentityServer4流中,但无法使它们显示在
/userinfo
端点中

我现在只使用“内存中”配置,因此在这里,我用我的自定义范围创建了一个新的
IdentityResource

新标识资源{
DisplayName=“我的自定义资源”,
Name=“mycustom”,
UserClaims=新列表{
“mycustom.myvalue”
}
}
我已将我的客户设置为能够使用此功能:

新客户端{
允许范围={
IdentityServerConstants.StandardScopes.OpenId,
“我的习惯”
}
}
然后,每当登录成功时,我都会执行以下操作来登录用户,然后再重定向回
/authorize/callback

wait_events.RaiseAsync(新用户登录成功事件( “提供者”, “providerUserID”, “主观性”, "姓名);; 等待HttpContext.SignInAsync( “主题”, “姓名”, 新建AuthenticationProperties(), 新索赔(“mycustom.myvalue”、“987654321”); 现在,我可以使用
?scope=openid+mycustom
执行完整的
授权
流程,但是当我调用
userinfo
端点时,它不会返回
mycustom.myvalue


我可能只遗漏了一些小细节,但我一辈子都搞不清楚。。。那么,我还缺少什么来实现这一点呢?

它不起作用,因为当您通过
HttpContext.SignInAsync(…,new claim(“mycustom.myvalue”,“987654321”))添加声明时,
它只会在用户实际在场并且通过cookie身份验证创建
ClaimsPrincipal
时被保留

因为您正在执行返回到
/userinfo
的往返,它只会给您声明默认的
IProfileService
将正常返回,并且它不可能知道该额外声明

尝试直接将此声明添加到
TestUser
之一(如果您使用的是内存用户):

公共静态列表GetUsers()
{
返回新列表
{
新测试用户
{
SubjectId=“1”,
Username=“alice”,
Password=“Password”,
索赔=新[]
{
新索赔(“名称”、“Alice”),
新索赔(“网站”https://alice.com"),
新索赔(“mycustom.myvalue”、“987654321”)
}
}....

它不起作用,因为当您通过
HttpContext.SignInAsync(…,new claim(“mycustom.myvalue”,“987654321”))添加声明时,
仅当用户实际在场并且通过cookie身份验证创建了
ClaimsPrincipal
时才会保留该声明

因为您正在执行返回到
/userinfo
的往返,它只会给您声明默认的
IProfileService
将正常返回,并且它不可能知道该额外声明

尝试直接将此声明添加到
TestUser
之一(如果您使用的是内存用户):

公共静态列表GetUsers()
{
返回新列表
{
新测试用户
{
SubjectId=“1”,
Username=“alice”,
Password=“Password”,
索赔=新[]
{
新索赔(“名称”、“Alice”),
新索赔(“网站”https://alice.com"),
新索赔(“mycustom.myvalue”、“987654321”)
}
}....

我没有使用内存中的用户,所以我不能这样做。基本上我是在与某个第三方进行身份验证,当验证完成后,我从第三方获得一些值,需要将这些值添加到声明中,声明将从
userinfo
可见。我考虑了
IProfileService
,但这没有足够的信息确认呼叫第三方,因此我非常希望将这些值设置为接近重定向回
授权/回调
是的,我想你不能这样做。你需要直接将这些声明放入自定义
UserStore
中,或者实现自定义
IProfileService
。我查看了一个自定义
IProfileService
注意到,在访问令牌端点(
context.Caller==“ClaimsProviderAccessToken”
)时,在
上下文.Subject.Claims
中设置了“mycustom.myvalue”,但在访问userinfo端点时未设置该值。使用
上下文.IssuedClaims.AddRange(新声明[])会有多脏
何时调用令牌终结点以强制声明在userinfo终结点期间可用?添加上一条评论中描述的功能后,我可以看到,在请求userinfo终结点时,
context.Subject.Claims
确实包含
mycustom.myvalue
,但它仍然没有在userinf中返回o、 我想我可以再做一次
context.issueslaims.AddRange()
强制它进入,但这是它变脏的地方:)@GTHvidsten因此,您完全遵守了我在回答中所描述的内容,即为什么您的自定义声明在回调到
/userinfo
时不可用。
IProfileService
的存在正是出于此扩展性原因,如果您需要添加自定义用户声明s出于某种原因,那么就这样做吧,不管脏不脏。我没有使用内存中的用户,所以我不能这样做。基本上我是在与某个第三方进行身份验证,完成后,我从第三方获得一些值,需要将这些值添加到声明中,该声明将从
用户信息
中可见。我考虑了
IProfileService
,但这将没有足够的信息呼叫第三方,因此我非常希望将这些值设置为接近重定向回 public static List<TestUser> GetUsers() { return new List<TestUser> { new TestUser { SubjectId = "1", Username = "alice", Password = "password", Claims = new [] { new Claim("name", "Alice"), new Claim("website", "https://alice.com"), new Claim("mycustom.myvalue", "987654321") } }....