![](/img/trans.png)
[英]IdentityServer4 client for Password Flow not including TestUser claims in access token
[英]IdentityServer4 claims are not part of the token on hybrid flow
我正在嘗試構建混合流,並使用IdentityServer4對返回的訪問令牌進行聲明。 我正在使用QuickStart UI控件。
在用戶成功通過身份驗證之后,在我的AccountController
,我有以下代碼用於登錄:
await HttpContext.SignInAsync("anon@nymous.com", "anon@nymous.com", null, new Claim("MyName", "Ophir"));
在導致此流程的MVC網站中,在我要“保護”的頁面上,我具有以下代碼:
[Authorize]
public IActionResult RestrictedMvcResource()
{
var token = _httpContext.HttpContext.GetTokenAsync("access_token").Result;
var identity = User.Identity;
return View();
}
成功登錄后,調試器會將此代碼正常運行,並且獲取訪問令牌。
問題是,如果我解碼訪問令牌(我正在使用https://jwt.io/ ),我會看到名稱和主題,但看不到我已定義的MyName
聲明。
(我的系統中還有一個用於client_credentials
流,該流確實返回了對令牌的聲明-但它使用了不同的代碼流)。
如何為混合流返回令牌的聲明?
編輯:
解決此問題是兩件事的結合:
IProfileService
。 這是我的實現: public class ProfileService : IProfileService
{
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
context.AddRequestedClaims(context.Subject.Claims);
foreach (Claim claim in context.Subject.Claims)
{
if (context.IssuedClaims.Contains(claim))
continue;
context.IssuedClaims.Add(claim);
}
return Task.FromResult(0);
}
public Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true;
return Task.FromResult(0);
}
}
這將添加令牌上尚未存在的所有聲明。
HttpContext.SignInAsync
,必須傳遞聲明列表,否則context.Subject.Claims
集合中將沒有其他聲明。 如果要向令牌添加自定義聲明,則可以實現自定義IProfileService
。
您可以在Identity Server 4文檔中找到更多信息。
一個簡單的自定義配置文件服務的示例是:
public class CustomProfileService : IProfileService
{
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
context.AddRequestedClaims(context.Subject.Claims);
context.IssuedClaims.Add(new Claim("MyName", "Ophir"));
return Task.FromResult(0);
}
public Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true;
return Task.FromResult(0);
}
}
一旦有了它,只需將其注冊到DI:
services.AddTransient<IProfileService, CustomProfileService>();
每當請求access_token
或id_token
時,它將被調用。 如果您只想要特定類型令牌的額外聲明,則需要根據Ruard的注釋檢查context.Caller
。
編輯:另外,也可以按照Identity Server 4快速入門之一中的示例,將聲明直接添加到用戶配置中:
new TestUser
{
SubjectId = "1",
Username = "alice",
Password = "password",
Claims = new []
{
new Claim("MyName", "Ophir")
}
},
如果最終沒有實現自定義IProfileService
並繼續使用DefaultProfileService
,則還需要在配置中添加自定義IdentityResource
:
return new List<IdentityResource>
{
//..Your other configured identity resources
new IdentityResource(
name: "custom.name",
displayName: "Custom Name",
claimTypes: new[] { "MyName" });
};
任何希望在令牌中添加此聲明的客戶端都需要請求custom.name
范圍。
AspNet.Security.OpenIdConnect.Server不會序列化未設置目標的聲明。 我在使用OpenIdDict時遇到了這個問題。
嘗試這個:
var claim = new Claim("MyName", "Ophir");
claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken);
await HttpContext.SignInAsync("anon@nymous.com", "anon@nymous.com", null, claim);
您可能需要添加以下名稱空間:
using AspNet.Security.OpenIdConnect.Extensions;
using AspNet.Security.OpenIdConnect.Primitives;
我將身份聲明添加到身份服務器的令牌的過程分為兩個步驟。
通過像其他答案之一所示的自定義配置文件服務,您可以為用戶定義自己的聲明。
然后可以通過userinfo端點請求這些聲明。
或者,您創建一個名為IncludeNameInAccessToken的Api(資源),如果您請求將Api作為范圍,則默認將名稱聲明添加到訪問令牌中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.