AWS Custom Federation Broker: ошибка вызова конечной точки федерации 400 python
Я пытаюсь создать URL-адрес, который позволяет федеративным пользователям получать доступ к Консоли управления AWS, следуя [официальной документации][1]. Я использую Cognito с [расширенный 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]>
Что я не прав?
[EDIT] Не было ошибки в session_string (sessioId вместо sessionId)
session_string = '{{"sessionId" : "{}" , "sessionKey": "{}", "sessionToken" : "{}"}}'.format(session_id, session_key, session_token)
Теперь ответ 400 BAD REQUEST
<Response [400]>
0 ответов
Я добавил полный пример того, как настроить учетные данные и создать URL-адрес, который дает федеративным пользователям прямой доступ к Консоли управления AWS на GitHub.
Вот основная часть кода, создающего 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