【问题标题】:Boto3 AWS MFA authentication fails when run on Mac Native and PyCharm terminals, but works on VSCode terminalBoto3 AWS MFA 身份验证在 Mac Native 和 PyCharm 终端上运行时失败,但在 VSCode 终端上运行
【发布时间】:2022-12-11 14:01:38
【问题描述】:

我已经编写了一个脚本来使用 python SDK 和 Boto3 查询 DynamoDB 表。 AWS IAM 角色需要 MFA,并且使用 VSCode 终端(版本:1.71.1 - 通用)我可以成功地进行身份验证并运行以下命令以获取 session_token 以创建经过身份验证的 Dynamo DB 客户端:

def create_authenticated_dynamo_dict() -> dict:
    user_serial_number = input('Enter ARN serial number, e.g. arn:aws:iam::123456789012:mfa/user: ')
    user_role = 'arn:aws:iam::XXXXXXXXXXXXXXX:role/{role_name}'
    mfa = input('Enter the user device MFA code: ')
    client = boto3.client('sts')
    mfa_sts_client = client.get_session_token(
        DurationSeconds=900,
        SerialNumber=user_serial_number,
        TokenCode=mfa
    ) ...

但是,当我在 PyCharm (PyCharm 2022.2.2) 或本机 Mac 终端(M1 2020,macOS Monterey v 12.5.1)中运行相同的代码时,我收到来自 AWS 的额外(附加)MFA 请求(输入后MFA 代码到终端输入),并且身份验证失败并出现以下错误:

botocore.exceptions.ClientError: An error occurred (AccessDenied) when
calling the GetSessionToken operation: Cannot call GetSessionToken
with session credentials

我验证了 VSCode、PyCharm 和 macOS 终端的 zsh shell - 但显然 PyCharm/Mac 本机终端和 VSCode 之间存在一些配置差异。我想在 PyCharm 中运行它。最后,我想了解为什么会发生这种情况,特别是什么导致了对 MFA 令牌的额外请求,而应该从 client.get_session_token 的参数中读取它。

【问题讨论】:

    标签: amazon-web-services visual-studio-code pycharm boto3 zsh


    【解决方案1】:

    我最终能够使用以下步骤在 Pycharm、VSCode 和本机 OSX 终端上成功进行身份验证:

    1. 创建新的 boto3 sts 客户端。
    2. get_session_token 在此客户端上,带有用户 MFA 代码。
    3. 创建另一个新的 boto3 sts 客户端,使用来自第一个客户端的 credentials
    4. assume_role 与第二个客户端和用户 IAM 角色。
    5. 使用第二个客户端的凭据创建新的 boto3 DynamoDB 客户端。

      使用此客户端,我能够使用表名成功进行 DynamoDB 查询,如下所示:

      user_serial_number = input('Enter ARN serial number, e.g. arn:aws:iam::123456789012:mfa/user: ')
      role = input('Enter AWS Role: e.g. arn:aws:iam::XXXXXXXXXXXXXXXX:role/{name of aws role from credentials file}: ')
      mfa = input('Enter the MFA code: ')
      
      mfa_sts_client = boto3.client('sts')
      
      # Credentials are good for 1 hour
      mfa_credentials = mfa_sts_client.get_session_token(
          DurationSeconds=3600,
          SerialNumber=user_serial_number,
          TokenCode=mfa
      )['Credentials']
      
      # Create a new client with credentials from the MFA enabled session we created above:
      assumed_role_sts_client = boto3.client(
          'sts',
          aws_access_key_id=mfa_credentials['AccessKeyId'],
          aws_secret_access_key=mfa_credentials['SecretAccessKey'],
          aws_session_token=mfa_credentials['SessionToken']
      )
      
      # assume role with the authenticated client
      assumed_role_res = assumed_role_sts_client.assume_role(
          RoleArn=role,
          RoleSessionName='{session name can be anything}'
      )
      
      # get temporary credentials from the assumed role
      tmp_creds = assumed_role_res['Credentials']
      
      # create authenticated DynamoDB client with the temporary credentials
      dynamo_client = boto3.client(
          'dynamodb',
          region_name='{aws region of table, e.g. 'us-east-1'}',
          aws_access_key_id=tmp_creds['AccessKeyId'],
          aws_secret_access_key=tmp_creds['SecretAccessKey'],
          aws_session_token=tmp_creds['SessionToken']
      )
      
      response = dynamo_client.describe_table(
          TableName='{name_of_table}'
      )
      

    【讨论】:

      猜你喜欢
      • 2021-02-17
      • 2020-09-10
      • 1970-01-01
      • 2021-07-06
      • 2015-10-20
      • 2015-07-15
      • 2018-01-08
      • 1970-01-01
      • 2021-06-09
      相关资源
      最近更新 更多