如何在 JWT 中包含身份角色声明?

Posted

技术标签:

【中文标题】如何在 JWT 中包含身份角色声明?【英文标题】:How to include claim on Identity Roles in JWT? 【发布时间】:2020-03-05 06:54:00 【问题描述】:

我已经按照 Microsoft (https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-3.0) 的模板和说明在我的 Asp.Net 核心 Web API 应用程序中实现了身份验证和授权。

在身份验证 JWT 令牌中,我想在用户的身份角色中包含一个声明,以便我可以轻松地在我的 SPA 客户端应用程序中隐藏不必要的模块并在 API 控制器上快速授权。但是,默认的 JWT 不包括对角色的声明。

在我当前使用的中间件中,我可以配置 JWT 令牌以包含角色声明吗? 注意我没有为当前令牌创建任何定义,中间件自动为我创建了令牌。

编辑 我已更改配置,因此该角色是对用户的声明。此外,我的配置已更改,因此范围包括此声明。生成的令牌仍然不包括角色。

我的主应用程序同时托管 Web API 和身份验证服务器。包:

<PackageReference Include="Microsoft.AspNetCore.ApiAuthorization.IdentityServer" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.0.0" />

启动:

...
services.AddDefaultIdentity<AppUser>()
        .AddRoles<IdentityRole>()
        .AddEntityFrameworkStores<DbContext>();

services.AddAuthentication()
        .AddIdentityServerJwt();

services.AddIdentityServer()
    .AddApiAuthorization<PimUser, PimDbContext>(options =>
    
        options.IdentityResources.Add(new IdentityResource(
            name: "roles",
            displayName: "Roles",
            claimTypes: new List<string>"role")  Required = true);
        options.Clients.AddSPA("authAngular", spa =>
            spa.WithScopes("AppAPI", "openid", "profile", "roles")
                .WithClientId("pimAngular")
                .WithRedirectUri("https://localhost:5001/authentication/login-callback")
                .WithLogoutRedirectUri("https://localhost:5001/authentication/logout-callback"));
    );
...

app.UseAuthentication(); 
app.UseAuthorization(); 
app.UseIdentityServer();
...

将用户添加到角色并同时添加声明:

await userManager.AddToRolesAsync(user, role);
await userManager.AddClaimAsync(user, new Claim("role", role));

openid 的配置确实包含了新的作用域:

"scopes_supported": [
    "openid",
    "profile",
    "roles",
    "AppAPI",
    ...
],
"claims_supported": [
    ...
    "role"
]

当我查询 authClient 的配置时,我也得到了正确的范围:


  "authority": "https://localhost:5001",
  "client_id": "authAngular",
  "redirect_uri": "https://localhost:5001/authentication/login-callback",
  "post_logout_redirect_uri": "https://localhost:5001/authentication/logout-callback",
  "response_type": "code",
  "scope": "AppAPI openid profile roles"

生成的令牌仍然不包括角色声明。我错过了什么?

【问题讨论】:

【参考方案1】:

编辑后的配置确实有效,但只有在创建新数据库并删除所有以前的迁移之后。一定是有一些损坏的数据/方案给我搞砸了。

【讨论】:

以上是关于如何在 JWT 中包含身份角色声明?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 JWT 身份验证过滤器中抛出自定义异常

通过 ASP.NET 核心身份中的角色声明进行 JWT 身份验证

为啥在 JWT Token 中包含 Header 和 Payload?

如何在 Python 中使用 JWT 实现基于角色的身份验证

如何在 Ansible 角色中包含很多 var

ASP.NET Core Jwt 实现 signinmanager 声明