使用Service Bus REST API的共享访问签名(SAS)时返回401错误是什么原因?
问题核心错误点
你的代码存在3个直接导致401未授权的错误,与你使用的RootManageSharedAccessKey主密钥本身无关:
- 授权头构造逻辑错误:你已经提前生成了包含完整规则的
sasToken变量,但是构造请求Authorization头时又重复拼接了一次参数,还错误地把整个sasToken放到了sig(签名)字段的位置,导致签名完全不匹配。 - 访问策略名不一致:生成SAS签名时你使用的策略名为
RootManageSharedAccessKey,但构造请求头时skn(策略名)参数错误填写为things,两者不匹配直接触发权限校验失败。 - 资源范围规范问题:你要请求的资源是命名空间下的
things主题,如果你后续使用实体级别的共享访问策略,sr(资源范围)参数需要对应到具体的主题路径https://<< NAMESPACE >>.servicebus.windows.net/things,当前你使用的是命名空间级别的Root策略,这个点不是本次报错的核心原因,但属于需要注意的规范。
修正后核心代码
var baseUrl = "https://<< NAMESPACE >>.servicebus.windows.net/"; var key = "<< SHARED ACCESS KEY >>"; TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1); var week = 60 * 60 * 24 * 7; var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + week); string stringToSign = HttpUtility.UrlEncode(baseUrl) + "\n" + expiry; HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)); var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign))); // 生成的sasToken本身就是完整的授权头值 var sasToken = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", HttpUtility.UrlEncode(baseUrl), HttpUtility.UrlEncode(signature), expiry, "RootManageSharedAccessKey"); var msg = new HttpRequestMessage() { RequestUri = new Uri(baseUrl + "things"), Method = HttpMethod.Post }; msg.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json"); // 直接赋值即可,无需二次拼接 msg.Headers.Add("Authorization", sasToken); var client = new HttpClient(); var r = client.Send(msg); Console.WriteLine(r.StatusCode);
内容的提问来源于stack exchange,提问作者Mr AH
相关产品推荐
相关产品推荐

