You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Node.js 16.x Lambda发布AWS IoT MQTT消息遇ForbiddenException

问题:Lambda发布MQTT到AWS IoT时出现403 ForbiddenException

我创建了一个由AWS CloudWatch事件触发的Node.js 16.x Lambda函数,用于向AWS IoT发布MQTT消息。已经给函数附加了AWSIoTDataAccess策略(该策略应该授予IoT消息操作的完整权限),但执行时出现403权限错误。

代码实现

import AWS from "aws-sdk";
var iotdata = new AWS.IotData({
  endpoint: "xxxxxxxxxxxxxxxx.iot.amazonaws.com",
  region: "ca-central-1",
});

export async function handler(event, context) {
    /* do something */
    await requestHB(inactiveDevices);
}

async function requestHB(inactiveDevices) {
  if (inactiveDevices == null) return;
  const publishPromises = inactiveDevices.map(async (element) => {
    var params = {
      topic: "device/inactive",
      payload: JSON.stringify({ type: 0, imei: String(element.imei) }),
      qos: 0,
    };

    try {
      await iotdata.publish(params).promise();
      console.log("Message published successfully");
    } catch (error) {
      console.error("Error publishing message:", error);
    }
  });

  await Promise.all(publishPromises);
}

错误信息

2023-05-29T17:49:01.024Z    5208a53c-f0f8-409f-a64b-9e901be9aa80    ERROR   Error publishing message: ForbiddenException: null
    at Object.extractError (/var/task/node_modules/aws-sdk/lib/protocol/json.js:61:27)
    at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/rest_json.js:61:8)
    at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:686:14)
    at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:688:12) {
  code: 'ForbiddenException',
  time: 2023-05-29T17:49:01.023Z,
  requestId: '0779829a-7f5d-d298-f9da-08f1b6d83753',
  statusCode: 403,
  retryable: false,
  retryDelay: 24.36546771452397
}

403状态码表示请求无操作权限,但已配置完整权限策略,请问遗漏了什么配置?


解答

出现这个问题通常不是IAM策略的问题,而是**AWS IoT的事物策略(Thing Policy)**未正确配置,以下是具体排查和解决步骤:

1. 配置IoT事物策略允许发布目标主题

AWS IoT除了IAM权限外,还需要事物策略明确允许客户端(此处为Lambda)对指定主题device/inactive执行iot:Publish操作。

创建或更新事物策略,添加以下权限语句:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:ca-central-1:你的AWS账号ID:topic/device/inactive"
    }
  ]
}

2. 关联Lambda执行角色到IoT事物策略

在AWS IoT控制台的安全 -> 事物策略中,找到目标策略,点击附加身份,选择Lambda执行角色的ARN完成关联,确保Lambda作为IoT客户端能使用该策略。

3. 验证IAM策略的资源范围

虽然使用了AWSIoTDataAccess托管策略,仍需确认其资源覆盖范围。托管策略默认允许*资源,若有自定义限制,需确保包含以下权限:

{
  "Effect": "Allow",
  "Action": [
    "iot:Connect",
    "iot:Publish",
    "iot:Subscribe",
    "iot:Receive"
  ],
  "Resource": "*"
}

4. 核对IoT端点和区域配置

  • 确认代码中endpoint值与AWS IoT控制台设置页面的自定义端点一致
  • 确保代码指定的region(ca-central-1)与IoT资源(端点、事物策略等)所在区域完全匹配,跨区域访问会导致权限验证失败

内容的提问来源于stack exchange,提问作者tamptek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 12:15:10