使用库生成预签名WebSocket请求 - Amazon IoT Core
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用库生成预签名WebSocket请求

以下显示了如何生成预签名请求,以便您可以使用WebSocket库向服务发送请求。

为您的 IAM 角色添加WebSocket请求策略

要使用WebSocket协议调用网络分析器,请将以下策略附加到提出此请求的 Amazon Identity and Access Management (IAM) 角色。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iotwireless:StartNetworkAnalyzerStream", "Resource": "*" } ] }

创建预签名 URL

为您的WebSocket请求构造一个 URL,其中包含在应用程序和网络分析器之间建立通信所需的信息。为了验证请求的身份,WebSocket流式传输使用亚马逊签名版本 4 流程对请求进行签名。有关签名版本4的更多信息,请参阅 Amazon Web Services 一般参考中的签名 AmazonAPI 请求

要调用网络分析器,请使用 StartNetworkAnalyzerStream请求 URL。使用之前提到的 IAM 角色凭据对请求进行签名。URL的格式如下,出于可读性目的,添加了换行符。您必须在行 &X-Amz-SignedHeaders=host 之下添加配置名称。任何其他参数都应按字母顺序添加到此行之下。

以下示例演示了如何将此请求 URL 与配置名称 NaConfig 一起使用:

wss://api.iotwireless.<region>.amazonaws.com/start-network-analyzer-stream?configuration-name=NaConfig &X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Date=20220427T001057Z&X-Amz-SignedHeaders=host &X-Amz-Expires=300 &X-Amz-Credential=credential_number/account/region/iotwireless/aws4_request &X-Amz-Signature=c123456789098765a012c3a45d6789dd01234af5678bba9bbc0dbc112a3334d
注意

如果您的 URL 不包含配置名称,Amazon IoT Core则 LoRa WAN 将包含网络分析器配置的默认名称NetworkAnalyzerConfig_Default

GET wss://api.iotwireless.<region>.amazonaws.com/start-network-analyzer-stream?X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Credential=Signature Version 4 credential scope &X-Amz-Date=date &X-Amz-Expires=time in seconds until expiration &X-Amz-Security-Token=security-token &X-Amz-Signature=Signature Version 4 signature &X-Amz-SignedHeaders=host

对于签名版本 4 参数,请使用以下值:

  • X-Amz-Algorithm – 您在签名过程中使用的算法。唯一有效值为 AWS4-HMAC-SHA256

  • X-Amz-Credential – 以斜杠(“/”)分隔的字符串,它通过将您的访问密钥 ID 和凭证范围组件串联起来而形成。凭证范围包括采用 YYYYMMDD 格式的日期、Amazon 区域、服务名称和终止字符串 (aws4_request)。

  • X-Amz-Date – 创建签名的日期和时间。根据 Amazon Web Services 一般参考签名版本 4 中处理日期的说明生成日期和时间。

  • X-Amz-Expires – 凭证到期之前的时间长度(以秒为单位)。最大值为 300 秒(5 分钟)。

  • X-Amz-Security-Token – 临时凭证的签名版本 4 令牌。如果您指定此参数,则将其包含在规范请求中。更多信息,请参阅 AmazonIdentity and Access Management 中的请求临时安全凭据。

  • X-Amz-Signature – 您为请求生成的签名版本 4 签名。

  • X-Amz-SignedHeaders — 为请求创建签名时签名的标头。唯一有效值为 host

构建请求 URL 并创建签名版本 4 签名

要构造请求的 URL 并创建签名版本 4 签名,请使用以下步骤。

注意

此节中的示例采用伪代码。有关说明如何创建签名的示例 python 代码,请参阅用于生成预签名 URL 的示例 Python 代码

创建一个字符串,其中包含来自标准格式的请求的信息。这可确保 Amazon在收到请求时,计算出的签名与您在 任务 3:计算签名中计算出的签名相同。有关更多信息,请参阅 Amazon Web Services 一般参考中的 创建签名版本 4 的规范请求

  1. 为您应用程序中的请求定义变量。

    # HTTP verb method = "GET" # Service name service = "iotwireless" # Amazon Web Services 区域 region = "Amazon Web Services 区域" # Service streaming endpoint endpoint = "wss://api.iotwireless.region.amazonaws.com" # Host host = "api.iotwireless.<region>.amazonaws.com" # Date and time of request amz-date = YYYYMMDD'T'HHMMSS'Z' # Date without time for credential scope datestamp = YYYYMMDD
  2. 创建规范 URI(统一资源标识符)。规范 URI 是域与查询字符串之间的 URI 部分。

    canonical_uri = "/start-network-analyzer-stream"
  3. 创建规范标头和签名标头。请注意规范标头尾部的 \n

    • 追加小写标头名称,后跟冒号。

    • 追加该标头的值的逗号分隔列表。请勿对有多个值的标头进行值排序。

    • 追加一个新行(\n)。

    canonical_headers = "host:" + host + "\n" signed_headers = "host"
  4. 将算法与哈希算法匹配。您必须使用 SHA-256。

    algorithm = "AWS4-HMAC-SHA256"
  5. 创建凭证范围,该范围将派生密钥范围限定为发出请求的日期以及将请求发送到的区域和服务。

    credential_scope = datestamp + "/" + region + "/" + service + "/" + "aws4_request"
  6. 创建规范查询字符串。查询字符串值必须是 URL 编码,并且按名称排序。

    • 按字符代码点以升序顺序对参数名称进行排序。具有重复名称的参数应按值进行排序。例如,以大写字母 F 开头的参数名称排在以小写字母 b 开头的参数名称之前。

    • 请勿对 RFC 3986 定义的任何非预留字符进行 URI 编码,这些字符包括:A-Z、a-z、0-9、连字符 (-)、下划线 (_)、句点 (.) 和波形符 (~)。

    • 使用 %XY 对所有其他字符进行百分比编码,其中“X”和“Y”为十六进制字符(0-9 和大写字母 A-F)。例如,空格字符必须编码为 %20(不像某些编码方案那样使用“+”),扩展 UTF-8 字符必须采用格式 %XY%ZA%BC。

    • 对参数值中的任何等于 (=) 字符进行双重编码。

    canonical_querystring = "X-Amz-Algorithm=" + algorithm canonical_querystring += "&X-Amz-Credential="+ URI-encode(access key + "/" + credential_scope) canonical_querystring += "&X-Amz-Date=" + amz_date canonical_querystring += "&X-Amz-Expires=300" canonical_querystring += "&X-Amz-Security-Token=" + token canonical_querystring += "&X-Amz-SignedHeaders=" + signed_headers
  7. 创建负载的哈希。对于 GET 请求,负载为空字符串。

    payload_hash = HashSHA256(("").Encode("utf-8")).HexDigest()
  8. 组合所有元素以创建规范请求。

    canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash

待签字符串包含您的请求的元信息。在计算请求签名时,您可以使用该字符串登录下一步。有关更多信息,请参阅 Amazon Web Services 一般参考中的创建签名版本 4 签名字符串

string_to_sign=algorithm + "\n" + amz_date + "\n" + credential_scope + "\n" + HashSHA256(canonical_request.Encode("utf-8")).HexDigest()

您可以从您的 Amazon秘密访问密钥派生签名密钥。为了实现更高程度的保护,派生密钥特定于日期、服务和 Amazon区域。您可以使用派生密钥签名请求。有关更多信息,请参阅 Amazon Web Services 一般参考中的为 Amazon签名版本 4 计算签名

该代码假定您实施了函数 GetSignatureKey来派生签名密钥。有关更多信息,请参阅 Amazon Web Services 一般参考中的如何为签名版本 4 派生签名密钥的示例

函数 HMAC(key, data)表示以二进制格式返回结果的 HMAC-SHA256 函数。

#Create the signing key signing_key = GetSignatureKey(secret_key, datestamp, region, service) # Sign the string_to_sign using the signing key signature = HMAC.new(signing_key, (string_to_sign).Encode("utf-8"), Sha256()).HexDigest

在计算签名之后,将它添加到查询字符串。有关更多信息,请参阅 Amazon Web Services 一般参考中的向请求添加签名

然后,您可以使用WebSocket库来请求预签名的 URL。有关与 Python 一起使用的示例WebSocket客户端,请参阅 websocket-client 1.4.1。

#Add the authentication information to the query string canonical_querystring += "&X-Amz-Signature=" + signature # Sign the string_to_sign using the signing key request_url = endpoint + canonical_uri + "?" + canonical_querystring

后续步骤

现在,您可以在WebSocket库中使用请求 URL 向服务发出请求并查看消息。有关说明如何生成预签名 URL 的示例 Python 代码,请参阅用于生成预签名 URL 的示例 Python 代码