我正在運行 IdentityServer4 的 Skorubas 實作 https://github.com/skoruba/IdentityServer4.Admin
由于某種原因,我最終收到了一個帶有宣告型別“role”的角色宣告和一個包含當前用戶所有角色的陣列值:[“SkorubaIdentityAdministrator”,“MyRole”]
現在,如果我想使用 Authorize-attribute 保護“頁面”: [Authorize(Role="MyRole")]
這總是以拒絕訪問而告終,因為 ASP.net Core 期望具有相同宣告型別的多個宣告,因此在這種情況下,宣告將是
型別| 價值
角色:“SkorubaIdentityAdminAdministrator”
角色:“我的角色”
是否有任何“最佳實踐”來決議收到的宣告并在它們被 ASP.net 核心處理之前重新格式化它們,或者告訴 OpenIdConnect 擴展將陣列格式作為多個宣告處理?
uj5u.com熱心網友回復:
一般來說,JWT 中收到的宣告可以是陣列或物件,也可以是簡單型別。使用 .NET 屬性進行授權時處理此問題的方法是通過策略。
它們非常簡單,本 Curity 教程有一些示例。此代碼片段顯示整個 ClaimsPrincipal 可用于策略,因此您可以在用例中輕松處理陣列宣告:
options.AddPolicy("lowRisk", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(claim =>
claim.Type == "risk" && Int32.Parse(claim.Value) < 50
)
)
);
[HttpGet("lowrisk")]
[Authorize( Policy = "lowRisk")]
public IActionResult LowRisk()
{
return Ok();
}
uj5u.com熱心網友回復:
事實證明,您可以創建自己的 ClaimActions,在上面的示例中,我必須執行以下操作:
首先.. 創建一個新類:
public class RoleClaimAction : ClaimAction
{
private const string RoleClaimType = "role";
public RoleClaimAction() : base(RoleClaimType, ClaimValueTypes.String)
{
}
public override void Run(JsonElement userData, ClaimsIdentity identity, string issuer)
{
//Map array of roles to separate role claims
var roles = userData.TryGetStringArray(RoleClaimType)?.ToList();
if (roles!.Any())
{
foreach (var role in roles!)
{
AddRoleClaim(identity, role, issuer);
}
return;
}
//If we only have one role (not an array), add it as a single role claim
var singleRole = userData.TryGetString(RoleClaimType);
if(!string.IsNullOrEmpty(singleRole))
AddRoleClaim(identity, singleRole, issuer);
}
private void AddRoleClaim(ClaimsIdentity identity, string role, string issuer)
{
identity.AddClaim(new Claim(JwtClaimTypes.Role, role, ClaimValueTypes.String, issuer));
}
}
這將簡單地驗證用戶是否有一個稱為角色的宣告,并將陣列值重新映射到單獨的角色宣告,然后“掛鉤”到身份驗證框架中。
要添加您的 ClaimAction,只需將以下內容添加到您的 OpenIdConnectOptions 中:
options.ClaimActions.Add(new RoleClaimAction())
現在使用角色授權屬性,并且 User.IsInRole(string) 應該可以正常作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/416843.html
標籤:
下一篇:在控制器中獲取當前用戶
