ASP.NET Core 和 JSON Web 令牌 - 自定义声明映射

Posted

技术标签:

【中文标题】ASP.NET Core 和 JSON Web 令牌 - 自定义声明映射【英文标题】:ASP.NET Core and JSON Web Tokens - Custom claims mapping 【发布时间】:2021-09-02 04:09:14 【问题描述】:

ASP.NET Core 有自己的标准声明映射。 Read this 看看这个GitHub repository

我正在使用 Azure AD,NET5。

问题是 unique_name 被映射到 name,如果你真的很幸运,你最终会得到两个名称声明。对我来说,一个是我的全名,一个是我的电子邮件。

处理重复名称声明的代码。

string email = null;
var nameClaims = httpCtx.User
                        .FindAll(x => x.Type.Equals(ClaimTypes.Name))
                        .Where(x => x.Value.Contains("@")).ToList();
if(nameClaims.Any())

  email = nameClaims.First().Value;
     

添加授权的代码。

services  
 .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
 .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>

 options.Authority = openIdConnectOptions.Authority;
 options.TokenValidationParameters.ValidIssuer = openIdConnectOptions.ValidIssuer;
 options.TokenValidationParameters.ValidAudiences = openIdConnectOptions.ValidAudiences;
 options.MapInboundClaims = true;
);

如果您设置 MapInboundClaims = false 那么现在将有映射,并且所有声明都将保留名称。 这解决了我的重复名称声明问题,但也打破了角色在 ASP.NET Core 中的映射方式。

我想保留默认映射,并为我知道映射错误的类型添加我自己的映射。 或者删除所有映射并添加缺少的部分以使角色再次起作用。

【问题讨论】:

您可以操作静态的JwtSecurityTokenHandler.DefaultInboundClaimType 字典来自定义默认映射。 "[...] 但也打破了角色在 ASP.NET Core 中的映射方式"。这与 ASP.NET Core 无关,但 ClaimsIdentity 默认使用哪个声明来确定用户所属的角色。如果您关闭声明映射,“角色”声明将保持原样,因此您需要指示 JWT 堆栈改为使用该声明。您可以使用options.TokenValidationParameters.RoleClaimType = "role"; 执行此操作。如果名称映射也被破坏,您可以对 NameClaimType 执行相同操作。 【参考方案1】:

这就是我最终的结果。 现在声明名称没有变化。角色除外。我需要添加 MS 声明名称才能让角色在我的策略映射中发挥作用。

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Logging;

namespace EmployeeTrading.Server.Extensions

    public static partial class ServiceCollectionExtensions
    
        public static IServiceCollection AddBearerAuthentication(this IServiceCollection services,
            OpenIdConnectOptions openIdConnectOptions)
        
#if DEBUG
            IdentityModelEventSource.ShowPII = true;
#endif
            // // https://mderriey.com/2019/06/23/where-are-my-jwt-claims/
            // https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/a301921ff5904b2fe084c38e41c969f4b2166bcb/src/System.IdentityModel.Tokens.Jwt/ClaimTypeMapping.cs

            services
                .AddAuthentication("Bearer")
                .AddJwtBearer("Bearer", o =>
                
                    o.Authority = openIdConnectOptions.Authority;
                    o.TokenValidationParameters.ValidIssuer = openIdConnectOptions.ValidIssuer;
                    o.TokenValidationParameters.ValidAudiences = openIdConnectOptions.ValidAudiences;
                    o.MapInboundClaims = false;
                    o.TokenValidationParameters.RoleClaimType = "roles";
                );

            return services;
        
    

【讨论】:

以上是关于ASP.NET Core 和 JSON Web 令牌 - 自定义声明映射的主要内容,如果未能解决你的问题,请参考以下文章

无法将 JSON 发布到 ASP.NET Core RazorPage 处理程序

net core体系-web应用程序7asp.net core日志组件

如何在 Asp.net Core Web Api 中默认使用 Newtonsoft.Json?

在 ASP.NET Core Web api 中读取 JSON 值

Asp.net core 配置文件

Asp.Net Core 进阶 —— 读取appsettings.json