18

我正在尝试使用浏览器中的 Web 套接字连接到 AWS IoT。

我试过这个例子: https ://github.com/awslabs/aws-iot-examples/tree/master/mqttSample

另一个稍作修改,因此可以与 Cognito 身份池登录用户一起使用。 https://github.com/dwyl/learn-aws-iot/blob/master/src/js/utils/request.js#L27

如果我使用具有有效 IoT 策略的 IAM 用户,我可以成功连接,但如果我使用用户凭证,我会收到“101 Switching Protocols”响应,但随后会关闭。

与经过身份验证的用户关联的 IAM 角色是正确的,我可以签署请求并执行其他私有操作,例如调用 APIG 端点。套接字连接也没有响应 403。所以它可能不是权限问题。

还能是什么?

4

6 回答 6

20

对于未经身份验证的认知身份,“身份池已身份验证”角色足以允许连接到 IoT MQTT 代理。但是,对于经过身份验证的 cognito 身份,需要两件事:

  1. “身份池已验证”角色必须允许访问您需要的 IoT 操作(例如连接、发布等)。

  2. 您必须使用AttachPrincipalPolicy API将 IoT 策略(与附加到设备的策略完全相同)附加到认知身份

第 2 步是我今天早些时候被卡住的地方,因为在任何地方都不是特别清楚需要这样做。

AFAIK 无法从任何 AWS 网站将 IoT 策略附加到认知用户。但是,如果您在机器上设置了 AWS 命令​​行界面,则可以从那里进行设置。该命令如下所示:

aws iot attach-principal-policy --policy-name <iot-policy-name> --principal <cognito-identity-id>

可以使用 找到 cognito 身份 ID,Federated Identities > Your Pool > Identity browser或者您也可以在对CognitoIdentityCredentials.get呼叫的响应中找到它。看起来像这样us-east-1:ba7cef62-f3eb-5be2-87e5-fffbdeed2824

对于生产系统,您显然希望自动附加此策略,可能在用户注册时使用 lambda 函数。

可以在此页面上找到有关需要附加 IoT 策略的文档部分:

要使经过身份验证的 Amazon Cognito 身份通过 HTTP 在您的 AWS 账户中的 topic1 上发布 MQTT 消息,您必须指定两个策略,如此处所述。第一个策略必须附加到 Amazon Cognito 身份池角色并允许该池中的身份进行发布调用。第二个策略使用 AWS IoT AttachPrincipalPolicy API 附加到 Amazon Cognito 用户,并允许指定的 Amazon Cognito 用户访问 topic1 主题。

于 2016-10-28T13:14:34.583 回答
7

为了在前端实现 Caleb 的回答,我必须做几件事:

  1. 通过转到 IoT 控制台 > 安全 > 策略并将AWSIoTDataAccess策略内容复制并粘贴到其中来创建 IoT 策略(命名为“默认”)
  2. 将以下内联策略添加到我的 Cognito 身份池的身份验证角色:{"Effect": "Allow", "Action": ["iot:AttachPrincipalPolicy"], "Resource": ["*"]

然后我更新了我的前端代码,如下所示:

AWS.config.region = process.env.AWS_REGION;
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
  IdentityPoolId: process.env.AWS_IDENTITY_POOL,
  Logins: {
    'graph.facebook.com': FACEBOOK_ACCESS_TOKEN
  }
});
AWS.config.credentials.get(() => {
  const IoT = new AWS.Iot();
  IoT.attachPrincipalPolicy({
    policyName: 'default',
    principal: AWS.config.credentials.identityId
  }, (err, res) => {
    if (err) console.error(err);
    // Connect to AWS IoT MQTT
  });
});
于 2017-01-11T16:43:28.207 回答
5

这是一个代码示例,用于将 IoT 策略从 Lambda (NodeJS) 函数附加到 Cognito 用户 ID。

function attachPrincipalPolicy(device_id, cognito_user_id) {
    const iotMgmt = new AWS.Iot();
    return new Promise(function(resolve, reject) {
        let params = {
            policyName: device_id + '_policy',
            principal: cognito_user_id
        };
        console.log("Attaching IoT policy to Cognito principal")
        iotMgmt.attachPrincipalPolicy(params, (err, res) => {
            if (err) {
                console.error(err);
                reject(err);
            } else {
                resolve();
            }
        });
    });
}
于 2016-12-06T10:32:03.807 回答
5

我参考了 Caleb 和 senornestor 的答案,以下实现对我有用:

AWS.config.credentials = new AWS.CognitoIdentityCredentials({
  IdentityPoolId: AWSConfiguration.poolId,
  Logins: {
     'accounts.google.com': user.Zi.id_token
  }
});

var cognitoIdentity = new AWS.CognitoIdentity();

AWS.config.credentials.get(function(err, data) {
  if (!err) {
     console.log('retrieved identity: ' + AWS.config.credentials.identityId);

     var params = {
        IdentityId: AWS.config.credentials.identityId,
        Logins: {
           "accounts.google.com": user.Zi.id_token
        }
     };
     cognitoIdentity.getCredentialsForIdentity(params, function(err, data) {
        if (!err) {
           console.log('retrieved credentials');
           const IoT = new AWS.Iot();
           IoT.attachPrincipalPolicy({
              policyName: 'exampleIoTPolicy',
              principal: AWS.config.credentials.identityId
           }, (err, res) => {
              if (err) console.error(err);
           });  // Change the "policyName" to match your IoT Policy
        } else {
           console.log('error retrieving credentials: ' + err);
           alert('error retrieving credentials: ' + err);
        }
     });
  } else {
     console.log('error retrieving identity:' + err);
     alert('error retrieving identity: ' + err);
  }
});
于 2017-06-20T11:29:59.730 回答
2

这是一个示例应用程序,应该有助于演示如何使用 Cognito 对 IoT 进行身份验证:

https://github.com/awslabs/aws-iot-chat-example

有关明确说明,您可以阅读:

https://github.com/awslabs/aws-iot-chat-example/blob/master/docs/authentication.md

于 2017-12-12T01:05:32.407 回答
1

事实证明,即使在 2021 年,也有必要创建一个专用的 Lambda 函数来完成AttachPolicy(不是AttachPrincipalPolicy因为它已经过时)。如官方文档中所述

要将 AWS IoT Core 策略附加到 Amazon Cognito 身份,您必须定义一个调用 AttachPolicy 的 Lambda 函数。

其他答案显示了如何实现该 Lambda。

于 2021-05-23T20:22:53.773 回答