0

我正在尝试创建一个 URL,使联合用户能够按照 [官方文档][1] 访问 AWS 管理控制台。我将 Cognito 与 [enhanced authflow][2] 一起使用,以便使用用户名和密码对用户进行身份验证。这是代码:

################## 1. LOGIN ####################

cognito = boto3.client('cognito-idp', aws_access_key_id='', aws_secret_access_key='')
response = cognito.initiate_auth(
        ClientId = app_client_id,
        AuthFlow = 'USER_PASSWORD_AUTH',
        AuthParameters = {
             "USERNAME": username,
             "PASSWORD": password
        },
        ClientMetadata = { 'UserPoolId': user_pool_id }
)

id_token = response['AuthenticationResult']['IdToken'] 

################## 2. GET ID ####################

cognito_identity = boto3.client('cognito-identity', aws_access_key_id='', aws_secret_access_key='', region_name=region)

response = cognito_identity.get_id(
        IdentityPoolId = identity_pool_id,
        Logins = {
                'cognito-idp.{}.amazonaws.com/{}'.format(region, user_pool_id) : id_token 
        }
)

identity_id = response['IdentityId']

################## 3. RETRIEVE CREDENTIALS ####################

response = cognito_identity.get_credentials_for_identity(
        IdentityId = identity_id,
        Logins = {
            'cognito-idp.{}.amazonaws.com/{}'.format(region, user_pool_id) : id_token 
        }
)

access_key_id = response['Credentials']['AccessKeyId']
secret_key = response['Credentials']['SecretKey']
session_token = response['Credentials']['SessionToken']

对于下一步(承担角色并调用联合端点),我没有使用上面链接的官方文档中的示例,因为它使用的是 boto 而不是 boto3。这是代码:

sts_boto_3 = boto3.client('sts',  aws_access_key_id = access_key_id, 
                                   aws_secret_access_key = secret_key, 
                                   aws_session_token = session_token, 
                                   region_name = region)

    response = sts_boto_3.assume_role(
            RoleArn = role,
            RoleSessionName = role_session_name,
    )
    session_id = response['Credentials']['AccessKeyId']
    session_key = response['Credentials']['SecretAccessKey']
    session_token = response['Credentials']['SessionToken']
    session_string =  '{{"sessioId" : "{}" , "sessionKey": "{}", "sessionToken" : "{}"}}'.format(session_id, session_key, session_token)

    req_url = 'https://signin.aws.amazon.com/federation?Action=getSigninToken&SessionDuration={}&Session={}'.format(3600, urllib.quote_plus(session_string))
    r = requests.get(req_url)
    print r

结果是

<Response [503]>

我错了什么?

[编辑] session_string 中没有错误(sessioId 而不是 sessionId)

session_string =  '{{"sessionId" : "{}" , "sessionKey": "{}", "sessionToken" : "{}"}}'.format(session_id, session_key, session_token)

现在响应是 400 BAD REQUEST

<Response [400]>
4

1 回答 1

0

我添加了一个完整示例,说明如何设置凭证和构建 URL,使联合用户可以直接访问GitHub 上的 AWS 管理控制台。

这是构造 URL 的代码的显着部分:

def construct_federated_url(assume_role_arn, session_name, issuer, sts_client):
    """
    Constructs a URL that gives federated users direct access to the AWS Management
    Console.
    1. Acquires temporary credentials from AWS Security Token Service (AWS STS) that
       can be used to assume a role with limited permissions.
    2. Uses the temporary credentials to request a sign-in token from the
       AWS federation endpoint.
    3. Builds a URL that can be used in a browser to navigate to the AWS federation
       endpoint, includes the sign-in token for authentication, and redirects to
       the AWS Management Console with permissions defined by the role that was
       specified in step 1.
    For more information, see Enabling Custom Identity Broker Access to the AWS Console
    [https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html]
    in the AWS Identity and Access Management User Guide.
    :param assume_role_arn: The role that specifies the permissions that are granted.
                            The current user must have permission to assume the role.
    :param session_name: The name for the STS session.
    :param issuer: The organization that issues the URL.
    :param sts_client: A Boto3 STS instance that can assume the role.
    :return: The federated URL.
    """
    response = sts_client.assume_role(
        RoleArn=assume_role_arn, RoleSessionName=session_name)
    temp_credentials = response['Credentials']
    print(f"Assumed role {assume_role_arn} and got temporary credentials.")

    session_data = {
        'sessionId': temp_credentials['AccessKeyId'],
        'sessionKey': temp_credentials['SecretAccessKey'],
        'sessionToken': temp_credentials['SessionToken']
    }
    aws_federated_signin_endpoint = 'https://signin.aws.amazon.com/federation'

    # Make a request to the AWS federation endpoint to get a sign-in token.
    # The requests.get function URL-encodes the parameters and builds the query string
    # before making the request.
    response = requests.get(
        aws_federated_signin_endpoint,
        params={
            'Action': 'getSigninToken',
            'SessionDuration': str(datetime.timedelta(hours=12).seconds),
            'Session': json.dumps(session_data)
        })
    signin_token = json.loads(response.text)
    print(f"Got a sign-in token from the AWS sign-in federation endpoint.")

    # Make a federated URL that can be used to sign into the AWS Management Console.
    query_string = urllib.parse.urlencode({
        'Action': 'login',
        'Issuer': issuer,
        'Destination': 'https://console.aws.amazon.com/',
        'SigninToken': signin_token['SigninToken']
    })
    federated_url = f'{aws_federated_signin_endpoint}?{query_string}'
    return federated_url
于 2020-06-22T21:04:50.947 回答