You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Postman生成Azure IoT Hub设备注册SAS令牌遇未授权问题

Azure IoT Hub设备注册SAS令牌未授权问题排查

我用Postman预请求脚本生成SAS令牌用于Azure IoT Hub设备注册,一直收到**Unauthorized(未授权)**错误。sr和se参数看起来正常,怀疑问题出在签名部分。

现有预请求脚本

var resourceUri = "scopeId/registrations/deviceId" // The resource uri
var deviceId = "deviceId";

resourceUri = encodeURIComponent(resourceUri.toLowerCase()); // Encode the url

var expires = Math.ceil((Date.now() / 1000) + 10 * 60); // Expire the token 60 minutes from now

var toSign = resourceUri + "\n" + expires; // this is the string format to gen signature from

var crypted = CryptoJS.HmacSHA256(deviceId, CryptoJS.enc.Base64.parse("symmetrickKeyOfEnrollmentGroup"));

var signature = CryptoJS.HmacSHA256(toSign, crypted); // The signature generated from the decodedKey
var encodedUri = encodeURIComponent(CryptoJS.enc.Base64.stringify(signature)); // The url encoded version of the Base64 signature

// Construct authorization string (shared access signature)
var iotHubSasToken = "SharedAccessSignature sr=" + resourceUri + "&sig=" + encodedUri + "&se=" + expires +"&skn=registration";

console.log(iotHubSasToken);
postman.setGlobalVariable("token", iotHubSasToken);

生成的令牌

SharedAccessSignature sr=0ne002ee24e%2Fregistrations%2Fcxdlx3f3zv9xx3f3zq&sig=Ukz%2FPyyLaweLYmFq4gHUP%2BhiO7X%2FyQAE9noAaw4nuLU%3D&se=1659940252&skn=registration

错误截图

未授权错误截图

问题分析与修正方案

1. 签名生成逻辑错误

注册组场景下,需要先从注册组对称密钥派生设备专属密钥,再用派生密钥签名待签内容。你当前的代码错误地使用了派生密钥的哈希结果去签名,导致签名无效。

2. 待签名字符串格式错误

待签名的resourceUri应该使用原始小写值,而非已经encodeURIComponent后的版本,编码只用于最终令牌的sr参数。

3. 多余的skn参数

DPS注册组的SAS令牌不需要skn(共享访问策略名称)参数,该参数仅适用于IoT Hub服务级别的共享访问策略,需要移除。


修正后的预请求脚本

var scopeId = "你的Scope ID";
var deviceId = "你的设备ID";
var enrollmentGroupKey = "注册组对称密钥";

// 构造原始resourceUri并转小写(不编码)
var resourceUri = `${scopeId}/registrations/${deviceId}`.toLowerCase();

// 生成设备派生密钥:HMAC-SHA256(设备ID, 解码后的注册组密钥),再转Base64
var decodedGroupKey = CryptoJS.enc.Base64.parse(enrollmentGroupKey);
var derivedDeviceKey = CryptoJS.HmacSHA256(deviceId, decodedGroupKey);
var derivedDeviceKeyBase64 = CryptoJS.enc.Base64.stringify(derivedDeviceKey);

// 设置令牌过期时间(10分钟后)
var expires = Math.ceil((Date.now() / 1000) + 10 * 60);

// 构造待签名内容:原始resourceUri + 换行符 + 过期时间
var toSign = `${resourceUri}\n${expires}`;

// 用派生密钥签名待签内容
var signature = CryptoJS.HmacSHA256(toSign, CryptoJS.enc.Base64.parse(derivedDeviceKeyBase64));
var encodedSignature = encodeURIComponent(CryptoJS.enc.Base64.stringify(signature));

// 构造最终SAS令牌(移除skn参数)
var encodedResourceUri = encodeURIComponent(resourceUri);
var sasToken = `SharedAccessSignature sr=${encodedResourceUri}&sig=${encodedSignature}&se=${expires}`;

console.log(sasToken);
postman.setGlobalVariable("token", sasToken);

额外验证点

  • 确认注册组配置中允许设备注册,且设备ID格式符合要求
  • 检查本地时间与Azure服务器时间偏差不超过5分钟(避免过期时间校验失败)
  • 确保注册组对称密钥未被篡改,且正确解码使用

内容的提问来源于stack exchange,提问作者Liverpool

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 04:15:56