ServiceStack生成JWT的jti为数字,致新版本NuGet包解析失败求助
问题解决:ServiceStack JWT jti字段类型不兼容新版Microsoft JWT库
问题背景
升级ServiceStack至6.11、System.IdentityModel.Tokens.Jwt/Microsoft.IdentityModel.JsonWebTokens至7.3.1后,客户端解析JWT时出现IDX12723、IDX11020错误,原因是ServiceStack生成的jti字段为数字类型,而RFC7519规定jti必须是字符串,新版Microsoft JWT库严格执行该规范导致解析失败。
问题解答
1. ServiceStack中JWT的jti字段是在哪里添加的?
jti字段是在JwtAuthProvider(包括其子类JwtAuthProviderReader)的CreateJwtPayload方法中生成并添加到JWT Payload里的,默认逻辑是使用递增的长整型数字作为jti的值。
2. 能否修改jti的数据类型?
可以修改,不需要修改ServiceStack官方源码包,通过自定义JWT认证提供者即可实现:
- 继承
JwtAuthProvider类,重写CreateJwtPayload方法,将生成的数字类型jti转换为字符串; - 在AppHost中注册自定义的认证提供者替代默认实现。
示例代码:
// 自定义JWT认证提供者 public class CustomJwtAuthProvider : JwtAuthProvider { protected override Dictionary<string, object> CreateJwtPayload(IRequest req, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> reqInfo) { // 先调用基类生成默认Payload var payload = base.CreateJwtPayload(req, session, tokens, reqInfo); // 将数字类型的jti转为字符串 if (payload.TryGetValue("jti", out var jtiValue) && jtiValue is long jtiNumber) { payload["jti"] = jtiNumber.ToString(); } return payload; } } // 在AppHost中注册 public override void Configure(Container container) { Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[] { new CustomJwtAuthProvider { AuthKeyBase64 = "你的JWT密钥", ExpireTokensIn = TimeSpan.FromDays(7), // 其他JWT配置项... } })); }
3. 是否需要修改ServiceStack包中的类型?
不需要修改官方包。通过上述自定义扩展的方式,就能在生成JWT时将jti转为字符串类型,既符合RFC7519规范,又能兼容新版Microsoft JWT解析库,同时保留ServiceStack的其他功能不受影响。
补充提示:旧版ServiceStack生成数字类型
jti是早期实现未严格遵循RFC规范导致,新版Microsoft JWT库7.x版本后对规范校验更加严格,因此在生成端修改jti类型是最彻底的解决方式,避免后续其他解析工具出现类似兼容问题。
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

