NATS Auth Callout认证报错:授权请求声明异常求助
从错误日志和代码细节来看,核心问题是生成的JWT不符合NATS Auth Callout机制要求的格式,以下是具体问题点和修复方案:
关键问题分析
- JWT的
sub字段错误:当用户使用用户名/密码认证时,Auth Callout返回的JWT中sub字段应为用户名(如"alice"),而非request.Nats.UserNKey(该字段仅在NKey认证场景下有效)。 - NATS Claim格式不规范:
- 多余的
data和payload字段设置为-1不符合NATS JWT规范,需移除。 - 缺少用户所属的
account字段,必须指定用户关联的目标账户(如配置中的ACC)。
- 多余的
- JWT受众(
aud)字段错误:aud应设置为目标账户的公共NKey,而非服务器ID,确保JWT与指定账户绑定。
修复后的代码示例
private static string CreateUserJwt(User user, AuthorizationRequest request){ var issuerKey = "SAAH3RHRIFXZGSPDONXD3X2LK4LUSQSEPFXFIROLEH6C2UJBHHTVGX5KLI"; var IssuerPublicKey = "ABC53VGEEBXCIWW4AJKLL2JMVPUUXXF74LCM3Q6AHLPWKH5JLDO7VCGQ"; // 提前为ACC账户生成的公共NKey,需与配置文件中一致 var targetAccountPubKey = "ACC_ACCOUNT_PUBKEY"; var keyPair = Nkeys.FromSeed(issuerKey); var jwtHeader = new { typ = "JWT", alg = "ed25519-nkey" }; var natsData = new { type = "user", version = 2, account = targetAccountPubKey, // 指定用户所属账户 pub = new { allow = new[] { "test.>" } }, sub = new { allow = new[] { "test.>" } } // 移除不符合规范的data、payload字段 }; var jwtPayload = new { aud = targetAccountPubKey, // 绑定到目标账户公钥 jti = Guid.NewGuid().ToString().Replace("-", "").ToUpper(), iat = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), iss = IssuerPublicKey, name = user.Username, sub = user.Username, // 替换为用户名 nats = natsData }; string encodedHeader = Base64UrlEncode(JsonConvert.SerializeObject(jwtHeader)); string encodedPayload = Base64UrlEncode(JsonConvert.SerializeObject(jwtPayload)); string signingInput = $"{encodedHeader}.{encodedPayload}"; byte[] signingBytes = Encoding.UTF8.GetBytes(signingInput); byte[] signature = keyPair.Sign(signingBytes); string encodedSignature = Base64UrlEncode(signature); string jwtToken = $"{encodedHeader}.{encodedPayload}.{encodedSignature}"; return jwtToken; }
修复后的nats-server.conf配置
确保目标账户配置了公钥,且auth_callout参数正确:
# Account configuration accounts { AUTH: { users: [{ user: auth, password: auth }] }, SYS: {}, ACC: { pubkey: "ACC_ACCOUNT_PUBKEY" # 与代码中的targetAccountPubKey一致 } } # Authorization & Auth Callout Configuration authorization { auth_callout { account: AUTH users: ["auth"] issuer: "ABC53VGEEBXCIWW4AJKLL2JMVPUUXXF74LCM3Q6AHLPWKH5JLDO7VCGQ" timeout: 5s # 可选:设置认证超时时间 } } # Set system account system_account: SYS
额外验证步骤
- 使用NATS CLI验证JWT格式合法性:
nats jwt verify -f 生成的JWT文件 -k ABC53VGEEBXCIWW4AJKLL2JMVPUUXXF74LCM3Q6AHLPWKH5JLDO7VCGQ - 确保Auth Callout服务响应
$SYS.REQ.USER.AUTH时,返回格式为{"jwt":"生成的JWT字符串"}的JSON结构,而非直接返回JWT文本。 - 查看NATS服务器日志,确认是否存在其他格式类错误提示。
内容的提问来源于stack exchange,提问作者Yusuf UZUN
相关产品推荐
相关产品推荐

