.NET 5部署IIS后调用JwtSecurityTokenHandler.WriteToken生成JWT报错
问题原因与解决方案
你遇到的报错本质是IIS运行环境下,JWT签名使用的密钥实际长度不符合HmacSha256算法要求,常见原因和对应解决方法如下:
1. 配置读取错误(最高发原因)
本地运行读取的是开发环境配置(比如appsettings.Development.json),部署到IIS后默认读取生产环境配置,大概率是服务器上的配置文件没有正确填写JWTSettings:SecretKey,或者IIS的站点配置、环境变量覆盖了该配置项,导致实际读取到的密钥为空、长度不足,和你本地测试用的密钥不一致。
排查方法:
取消你代码中注释的测试段,注释掉JwtSecurityTokenHandler().WriteToken(token)相关逻辑,输出_jwtConfig.Value.SecretKey的实际值、以及Encoding.ASCII.GetBytes(_jwtConfig.Value.SecretKey).Length的字节长度,部署到IIS访问即可确认是否为配置读取问题。
2. 编码差异问题
你当前使用Encoding.ASCII转码密钥,如果密钥包含ASCII范围外的字符,本地系统和IIS服务的默认编码差异会导致转出来的字节数组长度不符合预期。
解决方法:将所有转码密钥的代码替换为Encoding.UTF8.GetBytes,避免编码差异影响。
3. 密钥长度不满足算法要求
HmacSha256算法要求签名密钥长度至少为256位,也就是对应32个字节,你测试用的16字符仅对应128位,本地运行未报错通常是因为本地的Microsoft.IdentityModel.Tokens类库版本较低,未做强制校验,而服务器环境的类库版本更高,校验规则更严格。
解决方法:生成至少32位长度的纯ASCII可打印字符串作为密钥使用。
4. NuGet包版本不一致
如果项目中Microsoft.IdentityModel.Tokens、System.IdentityModel.Tokens.Jwt等相关依赖包版本不统一,或者发布时未携带正确版本的依赖文件,也会出现报错信息里参数类型显示为System.String、System.Int32的异常情况。
解决方法:
- 统一所有JWT相关NuGet包到同一稳定版本
- 发布前清空IIS站点的原有文件,重新发布完整项目包
内容的提问来源于stack exchange,提问作者Matthew Warr

