

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

# 使用 Amazon Cognito Identity 的授权
<a name="cog-iot-policies"></a>

存在两种类型的 Amazon Cognito Identity：经过身份验证的身份和未经身份验证的身份。当您的应用程序支持未经身份验证的 Amazon Cognito Identity 时，将不会执行身份验证，因此您不知道用户的身份。

**未经身份验证的身份：**对于未经身份验证的 Amazon Cognito Identity，您可以通过将 IAM 角色附加到未经身份验证的身份池来授予权限。我们建议您仅授予对希望可供未知用户使用的那些资源的访问权限。

**重要**  
对于连接 AWS IoT Core至的未经身份验证的 Amazon Cognito 用户，我们建议您在 IAM 策略中允许访问非常有限的资源。

**经过身份验证的身份：**对于经过身份验证的 Amazon Cognito Identity，您需要在两个位置指定权限：
+ 将 IAM 策略附加到经过身份验证的 Amazon Cognito Identity 池和
+ 将 AWS IoT Core 策略附加到 Amazon Cognito 身份（经过身份验证的用户）。

## 未经身份验证和身份验证的 Amazon Cognito 用户连接到的策略示例 AWS IoT Core
<a name="cog-iot-policies-auth-unauth-examples"></a>

以下示例显示了 Amazon Cognito Identity 的 IAM 策略和物联网策略中的权限。经过身份验证的用户想要发布到设备特定的主题（例如device/DEVICE\$1ID/status）。

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/Client_ID"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/device/Device_ID/status"
            ]
        }
    ]
}
```

以下示例显示了 Amazon Cognito 未经身份验证角色的 IAM 策略中的权限。未经身份验证的用户希望发布到不需要身份验证的非设备特定主题。

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:client/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/non_device_specific_topic"
            ]
        }
    ]
}
```

## GitHub 例子
<a name="cog-iot-policies-github"></a>

以下示例 Web 应用程序 GitHub 展示了如何将对经过身份验证的用户的策略附件纳入用户注册和身份验证流程。
+ [MQTT publish/subscribe React Web 应用程序使用 AWS Amplify 和 AWS IoT Device SDK for JavaScript](https://github.com/aws-samples/aws-amplify-react-iot-pub-sub-using-cp)
+ [使用 AWS Amplify、和 Lambda 函数的 MQTT publish/subscribe React Web 应用程序 AWS IoT Device SDK for JavaScript](https://github.com/aws-samples/aws-amplify-react-iot-pub-sub-using-lambda)

Amplify 是一组工具和服务，可帮助您构建与 AWS 服务集成的网络和移动应用程序。有关 Amplify 的更多信息，请参阅 [Amplify Framework Documentation](https://docs.amplify.aws/)。

这两个示例都执行了以下步骤。

1. 用户注册账户时，应用程序会创建 Amazon Cognito 用户池和身份。

1. 用户进行身份验证时，应用程序将创建策略并将其附加到身份。这授予用户发布和订阅的权限。

1. 用户可以使用应用程序发布和订阅 MQTT 主题。

第一个示例直接在身份验证操作中使用 `AttachPolicy` API 操作。以下示例演示如何在使用 Amplify 和 AWS IoT Device SDK for JavaScript的反应 Web 应用程序中实现此 API。

```
function attachPolicy(id, policyName) {
    var Iot = new AWS.Iot({region: AWSConfiguration.region, apiVersion: AWSConfiguration.apiVersion, endpoint: AWSConfiguration.endpoint});
    var params = {policyName: policyName, target: id};

    console.log("Attach IoT Policy: " + policyName + " with cognito identity id: " + id);
    Iot.attachPolicy(params, function(err, data) {
         if (err) {
               if (err.code !== 'ResourceAlreadyExistsException') {
                  console.log(err);
               }
          }
         else  {
            console.log("Successfully attached policy with the identity", data);
         }
     });
}
```

此代码出现在 [AuthDisplay.js](https://github.com/aws-samples/aws-amplify-react-iot-pub-sub-using-cp/blob/d1c307b36357be934db9dda020140fa337709cd9/src/AuthDisplay.js#L45) 文件中。

第二个示例在 Lambda 函数中实现 `AttachPolicy` API 操作。以下示例说明 Lambda 如何使用此 API 调用。

```
iot.attachPolicy(params, function(err, data) {
     if (err) {
           if (err.code !== 'ResourceAlreadyExistsException') {
              console.log(err);
              res.json({error: err, url: req.url, body: req.body});
           }
      }
     else  {
        console.log(data);
        res.json({success: 'Create and attach policy call succeed!', url: req.url, body: req.body});
     }
 });
```

此代码出现在[app.js](https://github.com/aws-samples/aws-amplify-react-iot-pub-sub-using-lambda/blob/e493039581d2aff0faa3949086deead20a2c5385/amplify/backend/function/amplifyiotlambda/src/app.js#L50)文件的 `iot.GetPolicy` 函数中。

**注意**  
当您使用通过 Amazon Cognito 身份池获得的 AWS 证书调用该函数时，您的 Lambda 函数中的上下文对象包含的值为。`context.cognito_identity_id`有关更多信息，请参阅下列内容。  
[AWS Lambda Node.js 中的上下文对象](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-context.html)
[AWS Lambda Python 中的上下文对象](https://docs.aws.amazon.com/lambda/latest/dg/python-context.html)
[AWS Lambda Ruby 中的上下文对象](https://docs.aws.amazon.com/lambda/latest/dg/ruby-context.html)
[AWS Lambda Java 中的上下文对象](https://docs.aws.amazon.com/lambda/latest/dg/java-context.html)
[AWS Lambda Go 中的上下文对象](https://docs.aws.amazon.com/lambda/latest/dg/golang-context.html)
[AWS Lambda C\$1 中的上下文对象](https://docs.aws.amazon.com/lambda/latest/dg/csharp-context.html)
[AWS Lambda 中的上下文对象 PowerShell](https://docs.aws.amazon.com/lambda/latest/dg/powershell-context.html)