まもなく:認証されていないアクセスと認証されたアクセスの両方の役割を持つフェデレーションIDプールがあります。認証されていないアクセスに問題はありません。しかし、認証されたアクセスに関しては、ユーザーはうまくログインしますが、認証されたユーザーの私の役割は実際には適用されません。Cognito IDプールで認証されたユーザーのMQTT接続
私はMQTT経由で通信する単純なindex.htmlとindex.jsファイルを持つs3バケットを持っています。
認証されたユーザーと認証されていないユーザーの両方のポリシーは、現在まったく同じに見え、かなり許容されています(もちろん、これは実際の運用には向いていませんが、 。だから、次のように両方のポリシーが見える:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
を、次のようにindex.jsに私は、認証されていないユーザーとしてMQTT接続を確立することができます
var region = 'eu-west-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'my-identity-pool-id',
});
AWS.config.credentials.clearCachedId();
AWS.config.credentials.get(function(err) {
console.log('accessKeyId:', AWS.config.credentials.accessKeyId);
if(err) {
console.log(err);
return;
}
var requestUrl = SigV4Utils.getSignedUrl(
'wss',
'data.iot.' + region + '.amazonaws.com',
'/mqtt',
'iotdevicegateway',
region,
AWS.config.credentials.accessKeyId,
AWS.config.credentials.secretAccessKey,
AWS.config.credentials.sessionToken
);
initClient(requestUrl);
});
initClient()
は、単にPaho
によるMQTT接続を確立します:
function initClient(requestUrl) {
var clientId = String(Math.random()).replace('.', '');
var rpcId = "smart_heater_" + String(Math.random()).replace('.', '');
var client = new Paho.MQTT.Client(requestUrl, clientId);
var connectOptions = {
onSuccess: function() {
console.log('connected');
// Now I can call client.subscribe(...) or client.send(...)
},
useSSL: true,
timeout: 3,
mqttVersion: 4,
onFailure: function (err) {
console.error('connect failed', err);
}
};
client.connect(connectOptions);
client.onMessageArrived = function (message) {
console.log("msg arrived: " + message);
};
}
そして、それだけで正常に動作します:connected
がコンソールに出力されます、と私は実際にサブスクライブ/送信することができます。
今、私は認証されたユーザーのために同じことをしようとしています。そのために、Cognito User Poolを追加してそこにユーザーを作成し、「アプリケーション」を作成し、認証プロバイダ「Cognito」を自分のIDプールに追加しました(適切なユーザープールIDとApp Client IDを使用)。 。ユーザーは、コードに記録されます、次のようになります。
var region = 'eu-west-1';
var poolData = {
UserPoolId: 'eu-west-1_XXXXXXXXX',
ClientId: 'ZZZZZZZZZZZZZZZZZZZZZZZZZ',
};
var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
var authenticationData = {
Username: 'myusername',
Password: 'mypassword',
};
var authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);
var userData = {
Username: 'myusername',
Pool: userPool
};
var cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
console.log('result:', result);
console.log('access token: ' + result.getAccessToken().getJwtToken());
var myUserPoolId = 'eu-west-1_XXXXXXXXX';
console.log('You are now logged in.');
// Add the User's Id Token to the Cognito credentials login map.
var logins = {};
logins['cognito-idp.' + region + '.amazonaws.com/' + myUserPoolId] = result.getIdToken().getJwtToken();
AWS.config.credentials.params.Logins = logins;
// finally, expire the credentials so we refresh on the next request
AWS.config.credentials.expired = true;
//call refresh method in order to authenticate user and get new temp credentials
AWS.config.credentials.refresh((error) => {
if (error) {
console.error(error);
} else {
console.log('Successfully logged!');
console.log('accessKeyId:', AWS.config.credentials.accessKeyId);
var requestUrl = SigV4Utils.getSignedUrl(
'wss',
'data.iot.' + region + '.amazonaws.com',
'/mqtt',
'iotdevicegateway',
region,
AWS.config.credentials.accessKeyId,
AWS.config.credentials.secretAccessKey,
AWS.config.credentials.sessionToken
);
initClient(requestUrl);
}
});
},
onFailure: function (err) {
alert(err);
},
newPasswordRequired: function(userAttributes, requiredAttributes) {
// User was signed up by an admin and must provide new
// password and required attributes, if any, to complete
// authentication.
// the api doesn't accept this field back
delete userAttributes.email_verified;
var newPassword = prompt('Enter new password ', '');
// Get these details and call
cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this);
},
});
ログイン部分が働いて得ることが容易ではありませんでしたが、今では正常に動作します:コンソールに、私は以下を参照してください。
You are now logged in.
Successfully logged!
accessKeyId: ASIAIRV4HOMOH6DXFTWA
接続時に次のエラーが表示されます。
connect failed: {invocationContext: undefined, errorCode: 8, errorMessage: "AMQJS0008I Socket closed."}
これは、実際に認証されたユーザーに適用されているロールがアクションを許可していないためと考えられます。iot:Connect
;
{
"Action": [
"iot:Connect"
],
"Resource": "*",
"Effect": "Deny"
},
は、接続しようとすると、その後、認証されていないユーザーが同じエラーAMQJS0008I Socket closed
を受け取ることになります:私は認証されていないユーザーのために、正確に同じエラーを再現することができますので、私は私が認証されていないユーザーのためのポリシーに次のように置けば、そう信じています。
認証されたユーザーの私のポリシーは、実際に認証されたユーザーに適用されないようです。
私はこの質問を書く前に多くを実験しました。現在、私のアイデンティティプールの設定で、「認証ロールの選択」で私は、「デフォルトの役割を使用」している、確かに私の認証ロール、選ぶべきである:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
をしかし、私はまた、ロールを選択します「を選択してみましたルールと一緒に私の役割を設定するルールを書いてください。
ユーザープールにグループを作成し、そこで同じロールを使用し、このグループにユーザーを追加し、アイデンティティプールの設定で「トークンからロールを選択」を設定しようとしました。
何も助けがありません。認証されたユーザーの場合は、このerrorMessage: "AMQJS0008I Socket closed."
というメッセージが表示され続けますが、認証されていないユーザーの場合は、ポリシーは同じですが、すべて正常に機能します。
何か助けていただければ幸いです。それに加えて、1つは、に、基本的に(各IDに(IAMない方針)のIoTポリシーを添付する必要があります。
だからAWSコンソールからこれを行う方法はありません、右のことですか? –