【问题标题】:AWS IOT connection using Cognito credentials使用 Cognito 凭证的 AWS IOT 连接
【发布时间】:2019-09-15 05:49:00
【问题描述】:

我在使用 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": [
                "*"
            ]
        }
    ]
}

第二个是IOT接入的策略:

{
    "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 身份池角色。此是之前在 IdentityPoolAuthRole 中定义的托管策略 AWSIoTDataAccess。

第二个策略必须使用 AWS IoT AttachPrincipalPolicy API 附加到 Amazon Cognito 用户。”

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

我该如何解决这个问题?

【问题讨论】:

    标签: python amazon-cognito amazon-iam aws-iot


    【解决方案1】:

    您是对的,您错过的步骤是使用 AttachPrincipalPolicy API(现已弃用并已替换为 Iot::AttachPolicy。)

    为此:

    • 创建物联网政策(IoT Core > Secure > Policies > Create)

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

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

      aws iot attach-policy --policy-name <iot-policy-name> --target <cognito-identity-id>

    aws-samples/aws-iot-chat-example 有一个更复杂的 AWS 示例,但它是用 JavaScript 编写的。我无法在 Python 中找到等效项,但是无论使用哪种语言,Cognito/IAM/IoT 配置步骤和所需的 API 调用都将保持不变。

    【讨论】:

    • 谢谢,但不清楚我到底在哪里做这件事。获得临时凭据后是否要执行此操作?
    • 你的代码没问题,这只是过程。与您必须创建身份池身份验证角色的方式相同,您还必须使用 CLI 中的 attach-policy 命令将策略附加到身份(似乎没有用户界面)。
    • 不,不起作用。我在 AWS IOT 服务中创建了一个新的 IOT 策略,我们称之为 MarcIOTAttachPolicy。然后我尝试了两种方法:(1)运行你给我的 AWS cli 命令,(2)使用 boto3 python 包: iot_client = boto3.client('iot', region_name=region_name) 然后 iot_client.attach_policy(policyName=cognito_user_policy_name ,目标=身份ID)。仍然挂起并超时。
    猜你喜欢
    • 2018-03-02
    • 2021-01-09
    • 2020-09-01
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 2016-09-25
    • 1970-01-01
    相关资源
    最近更新 更多