C#调用DUO Admin API添加用户遇40103签名无效问题求助
排查Duo API添加用户的40103无效签名问题
核心错误点分析
1. 错误使用Basic Auth而非Duo专属签名认证
Duo Admin API的认证机制不是Basic Auth,你当前用Authorization: Basic ...的方式完全不符合要求。正确的认证头格式应为Duo <integration_key>:<hmac_sha1_signature>,签名需要基于请求参数、时间、HTTP方法等信息用Integration Secret生成HMAC-SHA1哈希。
2. 请求参数键名错误
你的Form参数键写的是username:(带冒号),但Duo API要求的参数名是username,多余的冒号会导致请求内容与签名计算的内容不匹配,直接触发签名无效错误。
3. 冗余代码干扰
- 重复设置
Request.Content:先初始化了空的StringContent,之后又替换为FormUrlEncodedContent,属于冗余操作,可能影响签名计算时的内容一致性。 - 手动添加Host头:HttpClient会自动根据请求URI填充Host头,手动设置可能引发不必要的不一致。
修正后的代码示例
var client = new HttpClient(); var requestUri = new Uri("https://api-2cf9xxxx.duosecurity.com/admin/v1/users"); var request = new HttpRequestMessage(HttpMethod.Post, requestUri); // 构造正确的Form参数 var formData = new Dictionary<string, string> { {"username", ADAccountNameStr} }; var formContent = new FormUrlEncodedContent(formData); request.Content = formContent; // 获取用于签名计算的URL编码Form内容 var contentString = await formContent.ReadAsStringAsync(); // 构造签名所需的基础信息 var duoDate = DateTime.UtcNow.ToString("R"); // 严格使用RFC 1123格式时间 var method = request.Method.ToString().ToUpper(); var host = requestUri.Host; var path = requestUri.PathAndQuery; // 拼接签名基准字符串(注意换行符为\n,所有内容用ASCII编码) var signatureBase = $"{duoDate}\n{method}\n{host}\n{path}\n{contentString}"; // 用Integration Secret生成HMAC-SHA1签名 var integrationSecret = "你的Integration Secret"; using var hmac = new HMACSHA1(Encoding.ASCII.GetBytes(integrationSecret)); var signatureBytes = hmac.ComputeHash(Encoding.ASCII.GetBytes(signatureBase)); var signature = Convert.ToBase64String(signatureBytes); // 设置正确的认证头和日期头 request.Headers.Add("X-Duo-Date", duoDate); var integrationKey = "你的Integration Key"; request.Headers.Authorization = new AuthenticationHeaderValue("Duo", $"{integrationKey}:{signature}"); var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); var responseContent = await response.Content.ReadAsStringAsync();
额外注意事项
X-Duo-Date的时间必须和Duo服务器时间偏差不超过15分钟,否则会触发签名无效。- 签名计算全程使用ASCII编码,禁止用Unicode编码,否则哈希结果会出错。
- Form参数的排序要和
FormUrlEncodedContent自动排序一致(默认按字典序),确保签名计算的内容和实际发送的完全匹配。
内容的提问来源于stack exchange,提问作者Foadi
相关产品推荐
相关产品推荐

