AddJWTBearer 未使用 IdentityServer4 和 dotnetcore 2.0 填充角色

roles not being populated by AddJWTBearer using IdentityServer4 and dotnetcore 2.0

我正在使用具有以下配置的这些程序集:

我在 connect/token 请求令牌给了我一个正确的不记名令牌,当我调用一个使用 [Authorize(JwtBearerDefaults.AuthenticationScheme)] 和令牌的方法时,授权似乎正常工作。

然而,角色是空白/空的?
如何获取令牌请求以包含必要的 ASPNET 角色?

配置如下

services.AddAuthentication()
        .AddOpenIdConnect(
        o =>
        {
            o.Authority = "https://localhost:44319";
            o.ClientId = "api";
            o.ClientSecret = "secret";
            o.RequireHttpsMetadata = false;
            o.GetClaimsFromUserInfoEndpoint = true;
            o.TokenValidationParameters = new TokenValidationParameters
            {
                RoleClaimType = ClaimTypes.Role
            };
        })
        .AddJwtBearer(o =>
            {
                o.Authority = "https://localhost:44319";
                o.Audience = "api";
                o.RequireHttpsMetadata = false;
                o.TokenValidationParameters = new TokenValidationParameters
                {
                    RoleClaimType = ClaimTypes.Role
                };
                o.SaveToken = true;
            });

services.AddMemoryCache();
services.AddIdentity<ApplicationUser, ApplicationRole>(
        x =>
        {
            x.Password.RequireNonAlphanumeric = false;
            x.Password.RequireUppercase = false;
        })
    .AddEntityFrameworkStores<FormWorkxContext>()
    .AddDefaultTokenProviders()
    .AddIdentityServer();

services.ConfigureApplicationCookie(options =>
{
    options.LoginPath = "/login";
    options.LogoutPath = "/logout";
    options.Events.OnRedirectToLogin = this.ProcessStatusCodeResponse;
});

services.AddIdentityServer()
    // .AddSigningCredential("CN=rizacert")
    .AddDeveloperSigningCredential()
    .AddInMemoryIdentityResources(Config.GetIdentityResources())
    .AddInMemoryApiResources(Config.GetApis())
    .AddInMemoryClients(Config.GetClients())
    .AddAspNetIdentity<ApplicationUser>();

和config.cs

private const string Api = "api";
private const string ClientSecret = "secret";

public static IEnumerable<ApiResource> GetApis()
{
    return new List<ApiResource>
    {
        new ApiResource(Api, "formworkx api")
    };
}

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        new Client
        {
            ClientId = "api",
            AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
            RequireConsent = false,
            ClientSecrets = { new Secret(ClientSecret.Sha256()) },
            AllowedScopes =
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile,
                IdentityServerConstants.StandardScopes.OfflineAccess,
                "api"
            }
        }
    };
}

public static IEnumerable<IdentityResource> GetIdentityResources()
{
    return new List<IdentityResource>
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
    };
}

需要在 ApiResource 中请求声明类型。

public static IEnumerable<ApiResource> GetApis()
{
    return new List<ApiResource>
    {
        new ApiResource(
            Api,
            "formworkx api",
            new[]
            {
                // exhaustive list of claims in a new
                // dotnetcore 2.0 MVC application.
                "nbf",
                "exp",
                "iss",
                "aud",
                "aud",
                "client_id",
                "sub",
                "auth_time",
                "idp",
                "AspNet.Identity.SecurityStamp",
                ClaimTypes.Role,  // REQUESTED HERE
                "preferred_username",
                "name",
                "email",
                "email_verified",
                "scope",
                "amr"
            })
    };
}

此外,角色类型需要正确。

services.AddIdentity<ApplicationUser, ApplicationRole>(
   x =>
   {
       x.Password.RequireNonAlphanumeric = false;
       x.Password.RequireUppercase = false;
   })
   .AddEntityFrameworkStores<FormWorkxContext>()
   .AddDefaultTokenProviders()
   .AddIdentityServer();

   // NB (hours of debugging..., AddIdentityServer uses "role")
   services.Configure<IdentityOptions>(options => 
       options.ClaimsIdentity.RoleClaimType = ClaimTypes.Role);