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

C# 如何在IdentityServer4/Identity中配置角色的声明名称,c#,asp.net,asp.net-core,identity,identityserver4,C#,Asp.net,Asp.net Core,Identity,Identityserver4,我的问题: [Authorize(Roles=“L1”)和User.IsInRole(“L1”)正在查找声明名称“”,而不是“role” 在混凝土中: 我通过以下步骤()使用标准标识数据库创建了IdentityServer 4: 创建新项目 ASP.NET核心Web应用程序(.NET核心) ASP.NET核心1.1 Web应用程序 更改身份验证 个人用户帐户 添加IdentityServer4.AspNetIdentity+Config.cs+ 然后我创建了一个MVC客户机。身份验证

我的问题: [Authorize(Roles=“L1”)和User.IsInRole(“L1”)正在查找声明名称“”,而不是“role”

在混凝土中: 我通过以下步骤()使用标准标识数据库创建了IdentityServer 4:

  • 创建新项目
    • ASP.NET核心Web应用程序(.NET核心)
    • ASP.NET核心1.1
    • Web应用程序
    • 更改身份验证
      • 个人用户帐户
  • 添加IdentityServer4.AspNetIdentity+Config.cs+
然后我创建了一个MVC客户机。身份验证工作正常。我还得到了一份索赔清单

我使用中的表AspNetUsers、AspNetUserRoles和AspNetRoles为IdentityServer4配置角色。这些角色将添加到索赔名称为“role”的索赔中

如果我试图在MVC客户机中授权我的控制器操作,那么我的角色的声明名称似乎是错误的

我如何解决冲突?我是否必须将“角色”映射到“”

这是我在MVC客户端中的控制器:

[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;
    }
}
[路由(“api/[控制器]”)]
公共类公司控制器:控制器
{
[HttpGet]
//[Authorize(Roles=“L1”)]//这将查找索赔http://schemas.microsoft.com/ws/2008/06/identity/claims/role 而不是角色
公共异步任务GetCompanyAsync()
{
var c=User.identies.Count();//1
var nameofExpectedRoleclaimType=User.identies.First().RoleClaimType;//http://schemas.microsoft.com/ws/2008/06/identity/claims/role
var b0=User.HasClaim(NameOfExpectedRoleclaimType,“L1”);//false
var b1=User.HasClaim(“角色”、“L1”);//true
var b2=User.IsInRole(“L1”);//false;查找索赔http://schemas.microsoft.com/ws/2008/06/identity/claims/role;由[Authorize(Roles=“L1”)使用
var companies=await_crmApi.GetCompaniesAsync();
返回公司;
}
}

我找到了这个答案(),但我不知道如何“注册”这个原则

我为自己找到了答案。 我必须提到,我正在使用
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear()
避免对索赔名称进行重命名(请参见代码)

由此产生的问题是,
ClaimsPrinciple
仍在查找名为“”的角色

这可以通过
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"
      }

    });
  }
}

找到的答案不适用于asp.net-core,因为Microsoft.AspNetCore.Identity中不存在具有通用ClaimsPrinciple参数的UserManager。