Teams 出站WebHook HMAC签名验证不匹配问题求助
Teams WebHook HMAC验证不匹配问题修复
以下是你的代码中存在的关键问题及对应修复方案:
1. 签名编码方式不匹配
Teams生成的HMAC签名采用标准Base64编码,但你的代码使用了WebEncoders.Base64UrlEncode(该编码会替换+为-、/为_并移除末尾=),两者格式不兼容,需改用Convert.ToBase64String生成预期签名。
2. WebHook密钥处理错误
Teams提供的出站WebHook密钥本身是Base64编码字符串,你需要先将其Base64解码为字节数组,而非直接用Encoding.UTF8.GetBytes转换字符串。
3. 请求流未重置
读取完请求体后,需重置请求流的位置,否则后续控制器动作将无法读取请求内容。
修复后的完整代码
protected override async Task<AuthenticateResult> HandleAuthenticateAsync() { try { if (!Request.Headers.TryGetValue("Authorization", out var headerValue)) { return AuthenticateResult.Fail("Authorization header not found."); } var sentSignature = headerValue.ToString().Replace("HMAC ", string.Empty); if (string.IsNullOrWhiteSpace(sentSignature)) { return AuthenticateResult.Fail("Invalid Authorization header format."); } // 读取请求体并重置流位置,保证后续能正常读取 Request.Body.Position = 0; var requestBody = await new StreamReader(Request.Body, Encoding.UTF8).ReadToEndAsync(); Request.Body.Position = 0; if (string.IsNullOrWhiteSpace(requestBody)) { return AuthenticateResult.Fail("No content to authenticate."); } // 解码Teams提供的Base64格式密钥 if (!Convert.TryFromBase64String(Options.SecretKey, out var secretKeyBytes, out _)) { return AuthenticateResult.Fail("Invalid WebHook secret key format."); } using (var hmac = new HMACSHA256(secretKeyBytes)) { var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(requestBody)); var expectedSignature = Convert.ToBase64String(hashBytes); if (!string.Equals(sentSignature, expectedSignature, StringComparison.Ordinal)) { return AuthenticateResult.Fail("Invalid HMAC signature."); } } var claimsIdentity = new ClaimsIdentity(); var ticket = new AuthenticationTicket(new ClaimsPrincipal(claimsIdentity), Scheme.Name); return AuthenticateResult.Success(ticket); } catch (Exception ex) { return AuthenticateResult.Fail($"{ex.HResult}, {ex.Message}"); } }
额外验证提示
- 确认使用的密钥是Teams出站WebHook配置页提供的完整Base64字符串,无额外空格或换行。
- 调试时可打印
requestBody、sentSignature和expectedSignature的值,排查是否存在请求体被中间件修改、密钥复制错误等情况。
内容的提问来源于stack exchange,提问作者Aukum
相关产品推荐
相关产品推荐

