【问题标题】:Asp.Net Core 3.1 role based authorization for Web Api does not work基于 Web Api 的 Asp.Net Core 3.1 角色授权不起作用
【发布时间】:2021-03-12 02:38:26
【问题描述】:

我使用 Asp.Net Core 3.1 自带的 IdentityServer4 来实现基于角色的授权。

在调试时,我看到声明 http://schemas.microsoft.com/ws/2008/06/identity/claims/role 在进入服务器 Web Api 调用时被正确设置为“管理员”。但, Web Api 的[Authorize (Roles = "Administrator")] 总是无法返回 403 错误。请注意,简单的[Authorize] 可以正常工作。

我完成了https://github.com/dotnet/AspNetCore.Docs/issues/14944 中描述的调试步骤,但没有成功。感谢您是否可以帮助进行基于角色的授权工作。

代码sn-p:

AddOpenIdConnect(IdentityServerConstants.ProtocolTypes.OpenIdConnect, opt =>
            {
                opt.Authority = "http://localhost:44369";
                opt.RequireHttpsMetadata = false;

                opt.ClientId = "mvc";
                opt.ClientSecret = "secret";
                opt.ResponseType = "code";

                opt.SaveTokens = true;
                opt.GetClaimsFromUserInfoEndpoint = true;

                opt.Scope.Add("roles");
                opt.ClaimActions.MapUniqueJsonKey("roles", "role");
                opt.TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = JwtClaimTypes.Name,
                    RoleClaimType = JwtClaimTypes.Role,
                };
            }).

解码后的JWT如下:

{
  "nbf": 1606797785,
  "exp": 1606801385,
  "iss": "https://localhost:44369",
  "aud": "BaselineAPI",
  "client_id": "Baseline",
  "sub": "38ba2f2e-100d-eb11-ae75-00f48da696da",
  "auth_time": 1606752334,
  "idp": "local",
  "role": "Administrator",
  "scope": [
    "openid",
    "profile",
    "BaselineAPI"
  ],
  "amr": [
    "pwd"
  ]
}

更新: 用基于策略的授权替换角色。

将此添加到 Startup.cs:

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

将此添加到您的 Api 方法中:

[Authorize(Policy = "IsAdmin")]

【问题讨论】:

  • 您是否使用jwt.io 之类的工具检查了 JWT,以确保角色声明在 JWT 中并包含您期望的数据?
  • 感谢您的指点。是的,它确实显示了角色声明。我已经在问题中发布了 JWT

标签: asp.net-core identityserver4 asp.net-core-3.1


【解决方案1】:

IdentityServer 中的 Role 声明名称与 ASP.NET Core 中的 Role 声明名称不同。要映射它,您需要添加以下代码:

            options.TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = JwtClaimTypes.Name,
                RoleClaimType = JwtClaimTypes.Role,
            };

如果您还想添加其他声明,则需要使用以下命令将它们显式映射到本地用户 ClaimsPrincipal:

            options.ClaimActions.MapUniqueJsonKey("claimname", "claimname");

默认情况下,这些声明不包含在用户对象中。

【讨论】:

  • 我有这个,但还是不行。我已将 sn-p 添加到我的原始帖子中
猜你喜欢
  • 2020-05-19
  • 2021-09-04
  • 2020-02-13
  • 2019-09-29
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
  • 2020-05-18
  • 1970-01-01
相关资源
最近更新 更多