Skip to content

Commit

Permalink
Allow passing additional --console-role-arn and `--console-external…
Browse files Browse the repository at this point in the history
…-id` parameters in conjunction with `--print-console-signin-url`
  • Loading branch information
pdecat committed Oct 5, 2021
1 parent db59991 commit 43d26c3
Showing 1 changed file with 54 additions and 3 deletions.
57 changes: 54 additions & 3 deletions aws_adfs/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from os import environ
from platform import system

import boto3
import botocore
import botocore.exceptions
import botocore.session
Expand Down Expand Up @@ -97,6 +98,14 @@
is_flag=True,
help='Output a URL that lets users who sign in to your organization\'s network securely access the AWS Management Console.',
)
@click.option(
"--console-role-arn",
help="Role to assume for use in conjunction with --print-console-signin-url",
)
@click.option(
"--console-external-id",
help="External ID to pass in assume role for use in conjunction with --print-console-signin-url",
)
@click.option(
'--role-arn',
help='Predefined role arn to selects, e.g. aws-adfs login --role-arn arn:aws:iam::123456789012:role/YourSpecialRole',
Expand Down Expand Up @@ -141,6 +150,8 @@ def login(
stdout,
printenv,
print_console_signin_url,
console_role_arn,
console_external_id,
role_arn,
session_duration,
no_session_cache,
Expand Down Expand Up @@ -268,7 +279,9 @@ def login(
_emit_summary(config, aws_session_duration)
_print_environment_variables(aws_session_token, config)
elif print_console_signin_url:
_print_console_signin_url(aws_session_token, adfs_host)
_print_console_signin_url(
aws_session_token, adfs_host, console_role_arn, console_external_id
)
else:
_store(config, aws_session_token)
_emit_summary(config, aws_session_duration)
Expand Down Expand Up @@ -299,9 +312,43 @@ def _print_environment_variables(aws_session_token, config):
u"""{} AWS_DEFAULT_REGION={}""".format(envcommand, config.region))


def _print_console_signin_url(aws_session_token, adfs_host):
def _print_console_signin_url(
aws_session_token, adfs_host, console_role_arn, console_external_id
):
# The steps below come from https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html

if console_role_arn:
# Step 2: Using the access keys for an IAM user in your AWS account,
# call "AssumeRole" to get temporary access keys for the federated user

# Note: Calls to AWS STS AssumeRole must be signed using the access key ID
# and secret access key of an IAM user or using existing temporary credentials.
# The credentials can be in EC2 instance metadata, in environment variables,
# or in a configuration file, and will be discovered automatically by the
# client('sts') function. For more information, see the Python SDK docs:
# http://boto3.readthedocs.io/en/latest/reference/services/sts.html
# http://boto3.readthedocs.io/en/latest/reference/services/sts.html#STS.Client.assume_role

# FIXME: use botocore instead of boto3: https://github.com/boto/botocore/blob/1.21.49/botocore/credentials.py#L766
sts_connection = boto3.client(
"sts",
aws_access_key_id=aws_session_token["Credentials"]["AccessKeyId"],
aws_secret_access_key=aws_session_token["Credentials"]["SecretAccessKey"],
aws_session_token=aws_session_token["Credentials"]["SessionToken"],
)

if console_external_id:
aws_session_token = sts_connection.assume_role(
RoleArn=console_role_arn,
RoleSessionName="aws-adfs",
ExternalId=console_external_id,
)
else:
aws_session_token = sts_connection.assume_role(
RoleArn=console_role_arn,
RoleSessionName="aws-adfs",
)

# Step 3: Format resulting temporary credentials into JSON
url_credentials = {}
url_credentials['sessionId'] = aws_session_token['Credentials']['AccessKeyId']
Expand All @@ -313,7 +360,11 @@ def _print_console_signin_url(aws_session_token, adfs_host):
# the sign-in action request, a 12-hour session duration, and the JSON document with temporary credentials
# as parameters.
request_parameters = "?Action=getSigninToken"
request_parameters += "&SessionDuration=43200"

# https://signin.aws.amazon.com/federation endpoint returns a HTTP/1.1 400 Bad Request error with AssumeRole credentials when SessionDuration is set
if not console_role_arn:
request_parameters += "&SessionDuration=43200"

request_parameters += "&Session=" + urllib.parse.quote_plus(json_string_with_temp_credentials)
request_url = "https://signin.aws.amazon.com/federation" + request_parameters
r = requests.get(request_url)
Expand Down

0 comments on commit 43d26c3

Please sign in to comment.