使用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
相关产品推荐
相关产品推荐

