通过REST与IoT Central向IoT设备发命令的SAS Token问题
问题
微软官方文档介绍了通过REST调用向IoT设备发送命令的方法,该方法在IoT Hub中可正常运行。示例中通过az iot hub generate-sas-token -n <iothubName> --du <duration>生成对应SAS Token,但该方式在IoT Central中无法使用,因为其底层依赖的IoT Hub主机名未知。
我已通过DPS确定了对应的IoT Hub,并为设备生成了可用于向设备发送数据的SAS Token,但发现该Token与示例中的格式完全不同。示例请求格式如下:
https://<iothubName>.azure-devices.net/twins/<deviceId>/methods?api-version=2021-04-12 \ -H 'Authorization: SharedAccessSignature sr=iothubname.azure-devices.net&sig=x&se=x&skn=iothubowner' \ -H 'Content-Type: application/json' \ -d '{ "methodName": "reboot", "responseTimeoutInSeconds": 200, "payload": { "input1": "someInput", "input2": "anotherInput" } }'
请问造成这种差异的原因是什么?以及如何获取可用于发起命令的SAS Token?
解答
一、SAS Token格式差异的原因
- 权限范围不同:你生成的是设备级SAS Token,仅拥有单个设备的消息收发权限(比如上报遥测、接收云到设备消息);示例中的是IoT Hub级Token(带
skn=iothubowner标识),拥有对整个Hub的管理权限,支持调用设备直接方法、访问设备孪生等操作。 - 签名资源不同:设备级Token的签名资源(
sr字段)为<iothubName>.azure-devices.net/devices/<deviceId>,而Hub级Token的签名资源是<iothubName>.azure-devices.net,这是格式差异的核心原因。 - 用途场景不同:设备级Token供设备自身和Hub通信,而调用设备命令属于云端管理操作,需要的是服务级/Hub级权限的Token。
二、获取可用于发起命令的SAS Token的方法
方法1:使用IoT Central API Token
- 在IoT Central门户进入Administration > API Tokens,创建一个包含
Device Commands权限的API Token(比如选择Operator角色)。 - 直接将该Token作为请求头使用,格式为
Authorization: SharedAccessSignature <你的API Token>,调用IoT Central的命令REST接口即可,无需对接底层IoT Hub。
方法2:基于底层IoT Hub生成
- 登录Azure门户找到通过DPS定位到的IoT Hub,进入Shared access policies,选择一个拥有
ServiceConnect权限的策略(比如默认的iothubowner),复制其主密钥或副密钥。 - 手动生成Token:按照以下格式构造SAS Token:
各参数说明:SharedAccessSignature sr=<iothub-hostname>&sig=<signature>&se=<expiry>&skn=<policy-name><iothub-hostname>:你的IoT Hub主机名(如xxx.azure-devices.net)<signature>:通过HMAC-SHA256加密生成的签名,计算方式为URL编码(HMAC-SHA256(UTF8编码("<resourceURI>\n<expiry>"), "<密钥>"))<expiry>:Token过期的Unix时间戳(单位秒)<policy-name>:选择的共享访问策略名称
- Azure CLI生成:执行命令
az iot hub generate-sas-token -n <iothubName> --policy <policy-name> --du <duration>,生成的Token可直接用于调用底层IoT Hub的直接方法接口。
内容的提问来源于stack exchange,提问作者Init5
相关产品推荐
相关产品推荐

