如何在用户的索赔列表中保留多个ClaimTypes.Role值?

问题描述 投票:0回答:1

我正在构建ASP.NET Core(v3.1)模块,而我刚刚设法配置了OpenIdConnect身份验证。现在,我需要从API获取所有用户角色以授予或拒绝访问它们的权限,然后通过OnAuthorizationCodeReceived事件将多个Claim值添加到用户Claims列表中的同一Claim角色“ 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);

但是,显然,在我的Home控制器(经过身份验证的用户将被重定向到的位置)中,当我访问HttpContext.User时,除了“ Admin”之外,我似乎找不到我添加的任何角色。 “(我猜这是默认的ClaimTypes.Role值)。

[Authorize]
public IActionResult Index()
{
    if (User.IsInRole("SomeRole"))
    {
        return RedirectToAction("SomeAction", "SomeController");
    }
    else
    {
        return RedirectToAction("Forbidden", "Error");
    }
}

[通过阅读其他论坛和主题文章,我发现这可能是一个上下文持久性问题,我试图使用我的Account控制器中的代码来解决:

public async Task Login(string returnUrl = "/")
{
    await HttpContext.ChallengeAsync(
        "OIDC",
        new AuthenticationProperties
        {
            AllowRefresh = false,
            IsPersistent = true,
            RedirectUri = returnUrl
        });
}

一些示例说我可以使用context.Principal.AddIdentity(identity);来保留新的Claims列表,但是随后出现以下错误:

InvalidOperationException: only a single identity supported
IdentityServer4.Hosting.IdentityServerAuthenticationService.AssertRequiredClaims(ClaimsPrincipal principal)

总结起来,我必须找到一种方法来保留我添加到“用户的索赔”列表中的角色声明,但是到目前为止我没有成功。

c# .net-core openid-connect claims
1个回答
0
投票

对此进行更新,如果这对任何人都有用。

[我推断问题出在context.HttpContext.User = new ClaimsPrincipal(identity);上,我以前理解这是处理新声明的持久性的代码的一部分。

实际上,我确实注意到有一个context.Principal类型的ClaimsPrincipal属性,并且看起来它是实际的Current上下文,因此我对其进行了研究,并试图找出一种向其“ [ C0]“属性,它是只读的。

一段时间后,我发现以下对我来说很好的解决方案:

代替

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)));
© www.soinside.com 2019 - 2024. All rights reserved.