You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至Duende Identity Server后JWT Claims出现转义字符异常

问题原因
  • 双重序列化触发转义:升级到Duende Identity Server和.NET 6后,Claim的处理逻辑发生变化。你手动将appClaims序列化为JSON字符串并指定Claim类型为JsonClaimValueTypes.JsonArray,但系统会对该字符串再次执行序列化——把原本的JSON结构当成普通字符串处理,最终导致双引号被转义成\"。
  • .NET 6序列化行为变更:.NET 6的System.Text.Json默认配置与.NET Core 3.x存在差异,即使序列化代码未修改,输出的JSON字符串在后续流程中也更容易被重复转义。
解决方法

方案1:正确传递JSON结构(推荐)

不要手动序列化对象,使用JsonSerializer.SerializeToElement将appClaims转为JsonElement,再取其原始JSON文本作为Claim值。这样系统能识别这是JSON数组,不会重复序列化:

// 替换原序列化+添加Claim的代码
var jsonElement = JsonSerializer.SerializeToElement(appClaims);
claims.Add(new Claim(AppClaims, jsonElement.GetRawText(), JsonClaimValueTypes.JsonArray));

方案2:改用普通字符串类型(临时兼容)

如果暂时不想调整序列化逻辑,可以去掉JsonClaimValueTypes.JsonArray参数,让Claim按普通字符串处理。下游校验时,JsonSerializer.Deserialize会自动处理转义符,无需手动调用Replace("\\", ""):

claims.Add(new Claim(AppClaims, JsonSerializer.Serialize(appClaims)));

方案3:修复异步代码的阻塞问题(潜在风险)

你的代码中使用Select(x => x.Result)同步阻塞获取异步任务结果,在.NET 6中容易引发死锁或异常,建议改成标准异步写法:

// 替换原appClaims赋值代码
appClaims = await Task.WhenAll(userPermissions.Select(async x => new AppClaim
{
    Claims = x.AppRoleId != null ? await GetRoleClaims(x.AppRoleId, x.AppClaims) : x.Claims.Split(sepChar),
    AppName = x.AppName,
    Instance = x.Name
}));

验证方式

生成JWT后解码payload,确认AppClaims是纯JSON数组格式,而非带转义符的字符串:

"AppClaims": [{"AppName":"TTU","Instance":"TTU-dev-solihull","Claims":["StrategyManager-R","StrategyManager-RW",...]}]

内容的提问来源于stack exchange,提问作者Umair_007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 15:02:03