【问题标题】:ASP.NET claim policy not authorizingASP.NET 声明策略未授权
【发布时间】:2018-01-15 19:55:12
【问题描述】:

我已经设置了一个基本的 TestAdmin 帐户,以便在微服务应用程序中使用基于声明的身份验证。我的相关代码设置如下:

await userManager.AddClaimAsync(testAdmin, new Claim(ClaimTypes.Role, "NavInvoices"));

这显示在 AspNetUserClaims 数据库中,因此正在创建和保存。 我尝试了这两种方法来设置策略(我现在只检查是否存在任何 ClaimTypes.Role):

services.AddAuthorization(options =>
        {
            options.AddPolicy("NavInvoices2", policy => policy.RequireClaim(ClaimTypes.Role));
        });

services.AddAuthorization(options =>
        {
            options.AddPolicy("NavInvoices", policy =>
                policy.RequireAssertion(context =>
                    context.User.HasClaim(c =>
                        (c.Type == ClaimTypes.Role))));
        });

这是控制器:

[Authorize(Policy = "NavInvoices")]
    public IActionResult About()
    {
        ViewData["Message"] = "Your application description page.";


        return View();
    }

问题是当我遍历 user.claims 时没有角色。只有电子邮件、姓名等。在 SqlDB 中,只有我创建的角色存在。像姓名和电子邮件这样的其他东西都不在数据库中。因此,某处存在断开连接。如果有人熟悉的话,我将使用 IdentityServer4 的 Quickstart EFandAspNetIdentity 模板作为我的基础。

我已经用谷歌搜索了所有我能找到的东西,但到目前为止我什么也找不到。我认为有两个单独的存储正在进行,cookie 仅将其中一个传递给 webmvc 项目。有什么建议吗?

【问题讨论】:

  • 向数据库添加角色不会自动向声明添加角色。并非所有声明都会自动映射。你熟悉这篇文章吗? leastprivilege.com/2017/11/15/…
  • 谢谢你的文章。这是说我应该做options.ClaimActions.MapUniqueJsonKey("role", "role");?
  • 您不必像那样映射角色。但首先要确保角色作为声明包含在内。您可以使用 OpenIdConnectEvents 来确定收到了哪些声明。

标签: asp.net asp.net-identity identityserver4 claims-based-identity


【解决方案1】:

确保在将身份令牌传递给客户时将声明包含在身份令牌中。

客户端配置应该有以下几行:-

  new Client
   {
     ClientId = "yourclient",
     ClientName = "Your Client",
     // left out for brevity
     AlwaysSendClientClaims = true, 
     AlwaysIncludeUserClaimsInIdToken = true
   }

这应该允许所有用户声称通过。

您可以查看我之前回答的这个问题以获取更多信息,并查看我的 repo 中的示例:-

IdentityServer4 custom AuthenticationHandler can't find all claims for a user

【讨论】:

  • 我添加了这些行,但仍然没有运气。我会看看你之前的回答,看看我能不能让它工作。
  • 我通过查看 github 上的更改日志添加了您之前回答中的所有内容。仍然没有运气。我没有使用角色,而是直接将其添加给用户。这可能是个问题吗?
  • 我想通了!非常感谢您的回答!
  • 对于看到此内容的任何人,我需要更改 await userManager.AddClaimAsync(testAdmin, new Claim(ClaimTypes.Role, "NavInvoices")); ---to--- await userManager.AddClaimAsync(testAdmin, new Claim("NavInvoices", "NavInvoices"));
  • @Gutsee 在我看来 ClaimTypes.Role 是正确的。您更改了服务器,但您应该修改了客户端。如果您查看客户端上的声明,您可能会注意到 ClaimTypes.Role 被替换为另一种类型,因为 Microsoft 已知声明映射。清除入站 ClaimTypeMap 可能已经解决了这个问题:JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();