C# 如何持久化用户';索赔清单?
我正在构建一个ASP.NET核心(v3.1)模块,我刚刚配置了一个OpenIdConnect身份验证。现在,我需要从API获取所有用户角色,以便授予或拒绝对它们的访问,然后我通过类似以下事件的C# 如何持久化用户';索赔清单?,c#,.net-core,openid-connect,claims,C#,.net Core,Openid Connect,Claims,我正在构建一个ASP.NET核心(v3.1)模块,我刚刚配置了一个OpenIdConnect身份验证。现在,我需要从API获取所有用户角色,以便授予或拒绝对它们的访问,然后我通过类似以下事件的OnAuthorizationCodeReceived向用户声明列表中的同一声明角色“ClaimTypes.role”添加了多个声明值: OnAuthorizationCodeReceived = async (context) => { // Uses the authentication
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);
}
但是,很显然,在我的主控制器(即用户在经过身份验证后被重定向到的地方)中,当我访问HttpContext.user时,除了“Admin”(我猜这是默认的ClaimTypes.Role值)之外,我似乎找不到以前添加的任何角色
在阅读其他一些帖子、论坛和主题时,我发现这可能是一个上下文持久性问题,我试图在我的帐户控制器中使用以下代码来解决这个问题:
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=newclaimsprincipal(identity)的问题是什么代码>,我以前理解它是处理新声明持久性的代码的一部分
实际上,我注意到有一个上下文。Principal
类型的ClaimsPrincipal
属性的Principal
属性,看起来像是实际的当前上下文,所以我深入研究了它,并试图找到一种方法,将元素添加到其只读的“IEnumerable 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=newclaimsidentity(context.Principal.identity);
var listRoles=GenericProxies.RestGet(urlGetRoles,response.AccessToken);//获取对API的请求
listRoles.ForEach(role=>identity.AddClaim(新声明(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));
}
}
var identity=context.Principal.identity作为索赔实体;
如果(标识!=null)
{
var listRoles=GenericProxies.RestGet(urlGetRoles,response.AccessToken);//获取对API的请求
foreach(listRoles中的var角色)
{
identity.AddClaim(新声明(ClaimTypes.Role,Role));
}
}
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));
}
}