当前位置: 首页 > 知识库问答 >
问题:

AWS IOT连接使用Cognito凭据

姬高澹
2023-03-14

我使用Cognito凭据从python脚本连接到AWS IOT时遇到问题。我正在使用python中的AWS IOT SDK以及boto3包。以下是我正在做的:

首先,我建立了一个Cognito用户池,其中有两个用户有用户名和密码可以登录。我还设置了一个Cognito身份池,其中我的Cognito用户池是唯一的身份验证提供者。我不提供对未经验证身份的访问。标识池有一个身份验证角色,我将其称为“MyAuthRole”,当我转到IAM时,该角色附带了两个策略:一个是默认策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*",
                "cognito-identity:*"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

第二个是物联网接入政策:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "iot:*",
            "Resource": "*"
        }
    ]
}

接下来,我将使用python代码使用我的AWS IAM帐户凭据(访问密钥和密钥)来获取临时身份验证令牌,如下所示:

auth_data = { 'USERNAME':username , 'PASSWORD':password }
provider_client=boto3.client('cognito-idp', region_name=region)
resp = provider_client.admin_initiate_auth(UserPoolId=user_pool_id, AuthFlow='ADMIN_NO_SRP_AUTH', AuthParameters=auth_data, ClientId=client_id)
id_token=resp['AuthenticationResult']['IdToken']

最后,我尝试使用此令牌连接到AWS IOT,使用以下功能:

def _get_aws_cognito_temp_credentials(aws_access_key_id=None,aws_secret_access_key=None,
                region_name='us-west-2',account_id=None,user_pool_id=None,
                identity_pool_id=None,id_token=None):
    boto3.setup_default_session(aws_access_key_id=aws_access_key_id,
                aws_secret_access_key=aws_secret_access_key,
                region_name = region_name)
    identity_client = boto3.client('cognito-identity', region_name=region_name)
    loginkey = "cognito-idp.%s.amazonaws.com/%s" % (region_name,user_pool_id)
    print("loginkey is %s" % loginkey)
    loginsdict={
        loginkey: id_token
    }
    identity_response = identity_client.get_id(AccountId=account_id,
                IdentityPoolId=identity_pool_id,
                Logins=loginsdict)
    identity_id = identity_response['IdentityId']
    #
    # Get the identity's credentials
    #
    credentials_response = identity_client.get_credentials_for_identity(
                IdentityId=identity_id,
                Logins=loginsdict)
    credentials = credentials_response['Credentials']
    access_key_id = credentials['AccessKeyId']
    secret_key = credentials['SecretKey']
    service = 'execute-api'
    session_token = credentials['SessionToken']
    expiration = credentials['Expiration']
    return access_key_id,secret_key,session_token,expiration

最后,我创建了AWS IOT客户端,并尝试像这样连接:

myAWSIoTMQTTClient = AWSIoTMQTTClient(clientId, useWebsocket=True)
myAWSIoTMQTTClient.configureEndpoint(host, port)
myAWSIoTMQTTClient.configureIAMCredentials(temp_access_key_id,
                        temp_secret_key,
                        temp_session_token)
myAWSIoTMQTTClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTClient.configureOfflinePublishQueueing(-1)
myAWSIoTMQTTClient.configureDrainingFrequency(2)
myAWSIoTMQTTClient.configureConnectDisconnectTimeout(10)
myAWSIoTMQTTClient.configureMQTTOperationTimeout(5)
log.info("create_aws_iot_client", pre_connect=True)
myAWSIoTMQTTClient.connect()
log.info("create_aws_iot_client", post_connect=True, myAWSIoTMQTTClient=myAWSIoTMQTTClient)

问题是它pre_connect,然后就挂起来,最终超时。我得到的错误消息是:

AWSIoTPythonSDK.exception.AWSIoTExceptions.connectTimeoutException

我还在某个地方读到,可能还有其他政策必须附加:

“根据HTTP和WebSocketClients文档的策略,为了验证Amazon Cognito标识以通过HTTP发布MQTT消息,您必须指定两个策略。第一个策略必须附加到Amazon Cognito标识池角色。这是前面在Identit中定义的托管策略AWSIoTDataAccessyPoolAuthRole。

第二个策略必须使用AWS IoT attachPr的政策API附加到Amazon Cognito用户。"

但是,我不知道如何在python中或使用AWS控制台实现上述功能。

如何解决此问题?

共有1个答案

乐正晟
2023-03-14

你是正确的,你已经错过的步骤是使用attachPr的政策API(它现在贬值,并已被替换为Iot::Attach策略。)

为此:

>

将您希望附加到该策略的任何用户拥有的权限从共享的代码中授予该策略,这意味着只需复制第二个IAM策略。虽然你会想在生产中锁定它!

使用AWS CLI,您可以使用以下方法将此策略附加到您的认知用户:

aws物联网附加策略--策略名称

在AWS示例/AWS iot聊天示例中,有一个更为复杂的AWS示例,不过它是用JavaScript编写的。我在Python中找不到一个等价物,但是Cognito/IAM/IoT配置步骤和所需的API调用将保持不变,无论使用何种语言。

 类似资料:
  • 销毁已经创建的设备连接凭据。 请求方式: "|4|2|4|\r" 返回值: "|4|2|4|1|\r" 销毁成功 "|4|2|4|2|\r" 销毁失败 Arduino样例: softSerial.print("|4|2|4|\r");

  • 为了和Azure IoT设备通信,在创建设备之后会获得设备连接字符串,我们需要用这个字符串创建一个连接凭据。 请求方式: "|4|2|1|connectionString|" 参数 connectionString 设备连接字符串 返回值: "|4|2|1|1|\r" 创建成功 "|4|2|1|2|reason|\r" 创建失败 参数 reason 创建失败的原因 Arduino样例: softS

  • 根据文档,我了解了如何创建物联网,以及如何使用AWS物联网创建经过身份验证的用户。我的问题是如何有效地组合这些服务,以便每个用户都可以安全地访问他或她的多个设备。 假设Jane刚刚注册了该平台,并希望将她的灯泡设备连接到她的帐户。我们还假设她的灯泡设备上已经有证书和物联网中的策略,以便它可以连接到物联网平台,然后发布和订阅一些主题。为了简单起见,假设Jane可以通过简单地进行名为的API调用来创建

  • 应用程序是由angular开发的。 首先,用户应该使用Cognito登录。因此,在用户登录后,应用程序将获得CognitoUser数据,如其id令牌、访问密钥和会话令牌。 然后应用程序将开始连接到Iot Core,并尝试订阅或发布数据到我想要的主题。但我总是遇到Mqtt立即断开连接的情况。 以下是我的连接代码: 在运行代码之前,我还运行以下命令:

  • 我正在尝试使用curl,使用accessKey和secretKey,将请求发布到AWS中的es集群。我已经通过postman(这里的详细信息)成功地做到了这一点,您可以在这里指定AWS凭据,但我希望通过curl实现这一点。邮递员可以自动生成你的卷发请求,但我得到的只是错误。 这是生成的curl请求和响应 身份证已被更改以保护无辜者。 我已经检查了我所有的钥匙和地区,就像我说的,这是通过邮递员工作的