如何在 IdentityServer4/Identity 中配置角色的声明名称

koa*_*der 5 c# asp.net identity asp.net-core identityserver4

我的问题: [Authorize(Roles = "L1")] 和 User.IsInRole("L1") 正在寻找声明名称“ http://schemas.microsoft.com/ws/2008/06/identity/claims/role “而不是“角色”

具体来说: 我通过以下步骤(http://docs.identityserver.io/en/release/quickstarts/6_aspnet_identity.html)创建了一个带有标准身份数据库的 IdentityServer4 :

  • 创建新项目
    • ASP.NET Core Web 应用程序(.NET Core)
    • ASP.NET 核心 1.1
    • Web应用程序
    • 更改身份验证
      • 个人用户帐户
  • 添加 IdentityServer4.AspNetIdentity + Config.cs + ...

然后我创建了一个 MVC 客户端。身份验证工作正常。我也得到了一份索赔清单。

我在 IdentityServer4 中使用表 AspNetUsers、AspNetUserRoles 和 AspNetRoles 来配置角色。角色将添加到声明名称为“role”的声明中。

如果我尝试在 MVC-Client 中授权我的控制器操作,我的角色的声明名称似乎是错误的。

我该如何解决冲突?我是否必须将“角色”映射到“ http://schemas.microsoft.com/ws/2008/06/identity/claims/role ”?

这是我在 MVC-Client 中的控制器:

[Route("api/[controller]")]
public class CompaniesController : Controller
{
    [HttpGet]
    //[Authorize(Roles = "L1")] // This looks for the claim http://schemas.microsoft.com/ws/2008/06/identity/claims/role instead of role
    public async Task<IEnumerable<Company>> GetCompaniesAsync()
    {
        var c = User.Identities.Count(); // 1
        var nameOfExptectedRoleClaimType = User.Identities.First().RoleClaimType; // http://schemas.microsoft.com/ws/2008/06/identity/claims/role
        var b0 = User.HasClaim(nameOfExptectedRoleClaimType, "L1"); // false
        var b1 = User.HasClaim("role", "L1"); // true
        var b2 = User.IsInRole("L1"); // false; looks for claim http://schemas.microsoft.com/ws/2008/06/identity/claims/role; used by [Authorize(Roles = "L1")]

        var companies = await _crmApi.GetCompaniesAsync();

        return companies;
    }
}
Run Code Online (Sandbox Code Playgroud)

我找到了这个答案(/sf/answers/2395857691/),但我不知道如何“注册”CustomPrinciple。

koa*_*der 8

我已经为自己找到了答案。我不得不提到我正在使用 JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); 以避免重命名声明名称(请参阅代码)。

由此产生的问题是ClaimsPrinciple仍然寻找以“ http://schemas.microsoft.com/ws/2008/06/identity/claims/role ”命名的角色。

这可以通过OpenIdConnectOptions.TokenValidationParameters.

public class Startup
{
  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
  {
    // ...

    // Avoid claim mapping to old ms soap namespaces. Avoid replace "role" by "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
    {
      // ...

      // https://leastprivilege.com/2016/08/21/why-does-my-authorize-attribute-not-work/
      TokenValidationParameters = new TokenValidationParameters
      {
        NameClaimType = "name",
        RoleClaimType = "role", // The role claim type is named "role" instead of "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
      }

    });
  }
}
Run Code Online (Sandbox Code Playgroud)