[英]How do I persist multiple ClaimTypes.Role values in User's Claims list?
我正在構建一個 ASP.NET 核心(v3.1)模塊,我只是設法配置了一個 OpenIdConnect 身份驗證。 現在,我需要從 API 獲取所有用戶角色,以便授予或拒絕對它們的訪問權限,然后我通過OnAuthorizationCodeReceived
事件將多個聲明值添加到用戶聲明列表中的同一聲明角色“ClaimTypes.Role”,如下所示:
OnAuthorizationCodeReceived = async (context) =>
{
// Uses the authentication code and gets the access and refresh token
var client = new HttpClient();
var response = await client.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest()
{
Address = urlServer + "/connect/token",
ClientId = "hybrid",
Code = context.TokenEndpointRequest.Code,
RedirectUri = context.TokenEndpointRequest.RedirectUri,
}
if (response.IsError) throw new Exception(response.Error);
var identity = new ClaimsIdentity(context.Principal.Identity);
var listRoles = GenericProxies.RestGet<List<string>>(urlGetRoles, response.AccessToken); // GET request to API
listRoles.ForEach(role => identity.AddClaim(new Claim(ClaimTypes.Role, role)));
context.HttpContext.User = new ClaimsPrincipal(identity);
context.HandleCodeRedemption(response.AccessToken, response.IdentityToken);
}
在調試時,我注意到所有角色都添加到了用戶聲明列表之后:
context.HttpContext.User = new ClaimsPrincipal(identity);
但是,顯然,在我的主頁 controller 中(這是用戶在經過身份驗證后被重定向到的地方),當我訪問 HttpContext.User 時,我似乎找不到我之前添加的任何角色,除了“管理員”(我猜這是一個默認的 ClaimTypes.Role 值)。
[Authorize]
public IActionResult Index()
{
if (User.IsInRole("SomeRole"))
{
return RedirectToAction("SomeAction", "SomeController");
}
else
{
return RedirectToAction("Forbidden", "Error");
}
}
閱讀一些其他帖子論壇和主題,我發現這可能是一個上下文持久性問題,我試圖用我的帳戶 controller 中的這段代碼來解決這個問題:
public async Task Login(string returnUrl = "/")
{
await HttpContext.ChallengeAsync(
"OIDC",
new AuthenticationProperties
{
AllowRefresh = false,
IsPersistent = true,
RedirectUri = returnUrl
});
}
一些例子說我可以使用context.Principal.AddIdentity(identity);
為了保留新的聲明列表,但隨后出現以下錯誤:
InvalidOperationException: only a single identity supported
IdentityServer4.Hosting.IdentityServerAuthenticationService.AssertRequiredClaims(ClaimsPrincipal principal)
總而言之,我必須找到一種方法來持久化我添加到用戶聲明列表中的角色聲明,但直到現在我都沒有成功。
如果這對任何人有用,請對此進行更新。
我推斷出問題出在context.HttpContext.User = new ClaimsPrincipal(identity);
,我之前理解為處理新聲明的持久性的代碼部分。
實際上,我確實注意到有一個ClaimsPrincipal
類型的context.Principal
屬性,並且看起來它是實際的 Current 上下文,所以我深入研究它並試圖找出一種將元素添加到其“ IEnumerable<Claim> Claims
”的方法" 屬性是只讀的。
過了一會兒,我發現以下解決方案對我來說很好用:
代替
var identity = new ClaimsIdentity(context.Principal.Identity);
var listRoles = GenericProxies.RestGet<List<string>>(urlGetRoles, response.AccessToken); // GET request to API
listRoles.ForEach(role => identity.AddClaim(new Claim(ClaimTypes.Role, role)));
我試過了
var identity = context.Principal.Identity as ClaimsIdentity;
if(identity != null)
{
var listRoles = GenericProxies.RestGet<List<string>>(urlGetRoles, response.AccessToken); // GET request to API
foreach (var role in listRoles)
{
identity.AddClaim(new Claim(ClaimTypes.Role, role));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.