

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

# 使用 AWS IoT Core 凭证提供者授权直接调用 AWS 服务
<a name="authorizing-direct-aws"></a>

设备可以使用 X.509 证书通过 TLS 双向身份验证协议 AWS IoT Core 进行连接。其他 AWS 服务不支持基于证书的身份验证，但可以使用[AWS 签名版本 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) 格式的 AWS 凭据进行调用。[签名版本 4 算法](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html)通常要求呼叫者拥有访问密钥 ID 和私有访问密钥。 AWS IoT Core 具有凭据提供程序，允许您使用内置的 [X.509 证书](x509-client-certs.html)作为对请求进行身份验证的唯一设备身份。 AWS 这样就不再需要将访问密钥 ID 和私有访问密钥存储在您的设备上。

凭证提供程序使用 X.509 证书对调用方进行身份验证并颁发具有有限权限的临时安全令牌。该令牌可用于对任何 AWS 请求进行签名和身份验证。这种验证 AWS 请求的方式要求您创建和配置一个 [AWS Identity and Access Management (IAM) 角色](https://docs.aws.amazon.com/service-authorization/latest/reference/id_roles.html)并将相应的 IAM 策略附加到该角色，以便证书提供者可以代表您担任该角色。有关 AWS IoT Core 和 IAM 的更多信息，请参阅 [的身份和访问管理 AWS IoT](security-iam.md)。

 AWS IoT 要求设备将[服务器名称指示 (SNI) 扩展](https://www.rfc-editor.org/rfc/rfc3546#section-3.1)发送到传输层安全 (TLS) 协议，并在`host_name`字段中提供完整的端点地址。`host_name` 字段必须包含您调用的端点，并且必须是：
+ `aws iot [describe-endpoint](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot/describe-endpoint.html) --endpoint-type iot:CredentialProvider` 返回的 `endpointAddress`。

没有正确 `host_name` 值的设备尝试的连接将失败。

下图说明了凭证提供程序工作流程。

![\[AWS IoT Core 凭证提供者工作流程。\]](http://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/images/credentials-provider-diagram.png)


1.  AWS IoT Core 设备向凭证提供者发出 HTTPS 请求以获取安全令牌。该请求包括用于身份验证的设备 X.509 证书。

1. 凭证提供者将请求转发到 AWS IoT Core 身份验证和授权模块，以验证证书并验证设备是否有权请求安全令牌。

1. 如果证书有效且有权请求安全令牌，则 AWS IoT Core 身份验证和授权模块将返回成功。否则，它会向设备发送异常。

1. 成功验证证书之后，凭证提供程序将调用 [AWS Security Token Service (AWS STS)](https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html) 来代入您为它创建的 IAM 角色。

1. AWS STS 向凭证提供者返回临时的有限权限安全令牌。

1. 凭证提供程序将该安全令牌返回给设备。

1. 设备使用安全令牌对签 AWS 名版本 4 的 AWS 请求进行签名。

1. 请求的服务调用 IAM 来验证签名并根据附加到您为凭证提供程序创建的 IAM 角色的访问策略授权请求。

1. 如果 IAM 成功验证签名并授权请求，则请求成功。否则，IAM 将发送异常。

下一节介绍如何使用证书来获取安全令牌。编写此内容时，假定您已[注册了设备](register-device.html)并为它[创建并激活了您自己的证书](device-certs-your-own.html)。

## 如何使用证书来获取安全令牌
<a name="authorizing-direct-aws.walkthrough"></a>

1. 配置凭证提供程序代表您的设备代入的 IAM 角色。将以下信任策略附加到该角色。  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": {
           "Effect": "Allow",
           "Principal": {"Service": "credentials.iot.amazonaws.com"},
           "Action": "sts:AssumeRole"
       }
   }
   ```

   对于您要调用的每项 AWS 服务，请为该角色附加访问策略。凭证提供程序支持以下策略变量：
   + `credentials-iot:ThingName`
   + `credentials-iot:ThingTypeName`
   + `credentials-iot:AwsCertificateId`

   当设备在向 AWS 服务发出的请求中提供了事物名称时，凭证提供程序会将 `credentials-iot:ThingName` 和 `credentials-iot:ThingTypeName` 作为上下文变量添加到安全令牌。如果设备没有在请求中提供事物名称，则凭证提供程序将提供 `credentials-iot:AwsCertificateId` 作为上下文变量。您将事物名称作为 `x-amzn-iot-thingname` HTTP 请求标头的值进行传递。

   这三个变量仅适用于 IAM 策略，而不适用于 AWS IoT Core 策略。

1. 确保执行下一步（创建角色别名）的用户有权将新创建的角色传递给 AWS IoT Core。以下策略向 AWS 用户同时授`iam:PassRole`予`iam:GetRole`和权限。`iam:GetRole` 权限可让用户获取有关您刚创建的角色的信息。该`iam:PassRole`权限允许用户将角色传递给其他 AWS 服务。  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": {
           "Effect": "Allow",
           "Action": [
               "iam:GetRole",
               "iam:PassRole"
           ],
           "Resource": "arn:aws:iam::123456789012:role/your role name"
       }
   }
   ```

1. 创建 AWS IoT Core 角色别名。要直接呼叫 AWS 服务的设备必须知道在连接时要使用哪个角色 ARN。 AWS IoT Core对角色 ARN 进行硬编码并不是一个很好的解决方案，因为它需要您在角色 ARN 发生更改时更新设备。更好的解决方案是使用 `CreateRoleAlias` API 创建一个指向角色 ARN 的角色别名。如果角色 ARN 发生更改，您只需更新角色别名。无需在设备上进行任何更改。此 API 接受以下参数：  
`roleAlias`  
必需。一个标识角色别名的任意字符串。它充当角色别名数据模型中的主键。它包含 1-128 个字符，并且必须仅包含字母数字字符以及 =、@ 和 - 符号。允许大写和小写字母字符。角色别名名称区分大小写。  
`roleArn`  
必需。角色别名所指向的角色的 ARN。  
`credentialDurationSeconds`  
可选。凭证有效的时间长度（以秒为单位）。最小值为 900 秒（15 分钟）。最大值为 43200 秒（12 小时）。默认值为 3600 秒（1 小时）。  
 AWS IoT Core 凭证提供者可以颁发最长有效期为 43,200 秒（12 小时）的证书。凭证的有效期长达 12 小时，有助于通过将凭证缓存更长时间来减少对凭证提供程序的调用次数。  
`credentialDurationSeconds` 值必须小于或等于角色别名引用的 IAM 角色的最长会话持续时间。有关更多信息，请参阅《Identity [and Access Managem AWS ent 用户指南》中的修改角色最长会话时长 (AWS API)](https://docs.aws.amazon.com//IAM/latest/UserGuide/roles-managingrole-editing-api.html#roles-modify_max-session-duration-api)。

   相关此 API 的更多信息，请参阅 [CreateRoleAlias](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateRoleAlias.html)。

1. 将策略附加到设备证书。附加到设备证书的策略必须向设备授予代入角色的权限。您可以通过授予对角色别名执行 `iot:AssumeRoleWithCertificate` 操作的权限来做到这一点，如以下示例所示。  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "iot:AssumeRoleWithCertificate",
               "Resource": "arn:aws:iot:us-east-1:123456789012:rolealias/your role alias"
           }
       ]
   }
   ```

1. 向凭证提供程序发出 HTTPS 请求来获取安全令牌。提供以下信息：
   + *Certificate*：由于这是使用 TLS 双向身份验证的 HTTP 请求，因此，您在发出请求时必须向客户端提供证书和私有密钥。使用与注册证书时相同的证书和私钥 AWS IoT Core。

     要确保您的设备正在与之通信 AWS IoT Core （而不是模拟它的服务），请参阅[服务器身份验证](x509-client-certs.html#server-authentication)，点击链接下载相应的 CA 证书，然后将其复制到您的设备上。
   + *RoleAlias*：您为证书提供者创建的角色别名的名称。角色别名区分大小写，并且必须与中创建的角色别名相匹配 AWS IoT Core。
   + *ThingName*: 您在注册事物时创建 AWS IoT Core 的事物名称。这作为 `x-amzn-iot-thingname` HTTP 标头的值进行传递。仅当您在 AWS IoT Core 或 IAM 策略中使用事物属性作为策略变量时，才需要此值。
**注意**  
您在*ThingName*中提供的`x-amzn-iot-thingname`必须与分配给证书的 Thin AWS IoT g 资源的名称相匹配。如果不匹配，则返回 403 错误。

   在中运行以下命令 AWS CLI 以获取您的凭据提供程序终端节点 AWS 账户。相关此 API 的更多信息，请参阅 [DescribeEndpoint](https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeEndpoint.html)。有关启用 FIPS 的端点，请参阅 [AWS IoT Core- 凭证提供者端点](iot-connect-fips.md#iot-connect-fips-credential)。

   ```
   aws iot describe-endpoint --endpoint-type iot:CredentialProvider
   ```

   以下 JSON 对象是 **describe-endpoint** 命令的示例输出。它包含您用于请求安全令牌的 `endpointAddress`。

   ```
   {
       "endpointAddress": "your_aws_account_specific_prefix.credentials.iot.your region.amazonaws.com"
   }
   ```

   使用端点向凭证提供程序发出 HTTPS 请求以返回安全令牌。以下示例命令使用 `curl`，但您可以使用任何 HTTP 客户端。
**注意**  
Ro *leAlias* 名称区分大小写，并且必须与中创建的角色别名相匹配。 AWS IoT

   ```
   curl --cert your certificate --key your private key -H "x-amzn-iot-thingname: your thing name" --cacert AmazonRootCA1.pem https://your endpoint /role-aliases/your role alias/credentials
   ```

   此命令返回包含 `accessKeyId`、`secretAccessKey`、`sessionToken` 和过期的安全令牌对象。以下 JSON 对象是 `curl` 命令的示例输出。

   ```
       {"credentials":{"accessKeyId":"access key","secretAccessKey":"secret access key","sessionToken":"session token","expiration":"2018-01-18T09:18:06Z"}}
   ```

   然后，您可以使用`accessKeyId``secretAccessKey`、和`sessionToken`值对 AWS 服务请求进行签名。有关演 end-to-end示，请参阅*AWS 安全*博客上的 [“如何使用 AWS 凭据提供者博客文章来消除设备中对硬编码 AWS IoT 凭据的需求](https://aws.amazon.com/blogs/security/how-to-eliminate-the-need-for-hardcoded-aws-credentials-in-devices-by-using-the-aws-iot-credentials-provider/)”。