Невозможно выполнить публикацию или публикацию в AWS IoT с использованием MQTT через веб-сокеты
Я могу успешно подключиться к AWS IoT, используя MQTT через Websockets. Но при публикации или подписке соединение разрывается. Я полагаю, что это должно быть связано с политикой / разрешениями в AWS, но я уверен, что у меня есть правильные разрешения. Вот моя установка:
У меня есть лямбда-функция, которая создает подписанный URL-адрес с использованием STS acceptRole (разрешения в политике будут более жесткими, но я разрешил доступ ко всем функциям iot на всех ресурсах для тестирования):
const config = require('./config');
const crypto = require('crypto');
const v4 = require('aws-signature-v4');
const async = require('async');
const util = require('util');
const AWS = require('aws-sdk');
exports.handler = function (event, context) {
var fail = function (err) {
console.error(err);
context.fail('Oops, something went wrong with your request');
};
const iot = new AWS.Iot();
const sts = new AWS.STS({region: 'eu-west-1'});
var params = {
DurationSeconds: 3600,
ExternalId: Date.now().toString(),
Policy: JSON.stringify(
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:*",
],
"Resource": [
"*"
]
}
]
}
),
RoleArn: "arn:aws:iam::ACC_ID:role/iot_websocket_url_role",
RoleSessionName: 'expo-' + Date.now()
};
sts.assumeRole(params, function(err, stsData) {
if (err) {
fail(err);
return;
}
console.log(stsData);
const AWS_IOT_ENDPOINT_HOST = 'MYENDPOINT.iot.eu-west-1.amazonaws.com';
var url = v4.createPresignedURL(
'GET',
AWS_IOT_ENDPOINT_HOST,
'/mqtt',
'iotdata',
crypto.createHash('sha256').update('', 'utf8').digest('hex'),
{
key: stsData.Credentials.AccessKeyId,
secret: stsData.Credentials.SecretAccessKey,
protocol: 'wss',
expires: 3600,
region: 'eu-west-1'
}
);
url += '&X-Amz-Security-Token=' + encodeURIComponent(stsData.Credentials.SessionToken);
console.log(url);
context.succeed({url: url});
});
};
Представленная здесь RoleArn имеет следующую политику:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1488299712000",
"Effect": "Allow",
"Action": [
"iot:*"
],
"Resource": [
"*"
]
}
]
}
Я использую mqtt-элементы в проекте Polymer для моего кода внешнего интерфейса. Я подтвердил, что это работает правильно с помощью брокера сообщений Mosquitto, и Pub/Sub прекрасно с ним работает.
Я включил отладку на AWS IoT в CloudWatch. Вот журнал:
2017-03-24 15:58:07.027 TRACEID:REDACTED PRINCIPALID:REDACTED/REDACTED [INFO] EVENT:MQTT Client Connect MESSAGE:Connect Status: SUCCESS
2017-03-24 15:58:07.027 TRACEID:REDACTED PRINCIPALID:REDACTED [INFO] EVENT:MQTT Client Connect MESSAGE: IpAddress: REDACTED SourcePort: 41430
2017-03-24 15:58:07.059 TRACEID:REDACTED PRINCIPALID:REDACTED [INFO] EVENT:MQTTClient Subscribe TOPICNAME:doorLatch MESSAGE:Subscribe Status: AUTHORIZATION_ERROR
2017-03-24 15:58:07.059 TRACEID:REDACTED PRINCIPALID:REDACTED [INFO] EVENT:MQTTClient Subscribe MESSAGE: IpAddress: REDACTED SourcePort: 41430
2017-03-24 15:58:07.068 TRACEID:REDACTED PRINCIPALID:REDACTED [INFO] EVENT:MQTTClient Subscribe TOPICNAME:doorLatch MESSAGE:Subscribe Status: AUTHORIZATION_ERROR
2017-03-24 15:58:07.068 TRACEID:REDACTED PRINCIPALID:REDACTED [INFO] EVENT:MQTTClient Subscribe MESSAGE: IpAddress: REDACTED SourcePort: 41430
2017-03-24 15:58:07.069 TRACEID:REDACTED PRINCIPALID:REDACTED [INFO] EVENT:MQTT Client Disconnect MESSAGE:Disconnect Status: SUCCESS
2017-03-24 15:58:07.069 TRACEID:REDACTED PRINCIPALID:REDACTED [INFO] EVENT:MQTT Client Disconnect MESSAGE: IpAddress: REDACTED SourcePort: 41430
Таким образом, ясно, что проблема заключается в авторизации. Но политики в моей роли + функция acceptRole явно очень разрешающие и должны включать публикацию сообщений в AWS IoT.
Буду признателен за любую информацию по этому вопросу.
Изменить: я также поднял эту проблему на форумах AWS.
1 ответ
Невозможно использовать STS для соединения IoT. Единственный способ использовать MQTT поверх веб-сокетов - это использовать удостоверенную личность Cognito.