Skip to content

Commit f39bc0a

Browse files
committed
Allow passing additional --console-role-arn and --console-external-id parameters in conjunction with --print-console-signin-url
1 parent 02f5d78 commit f39bc0a

File tree

4 files changed

+108
-8
lines changed

4 files changed

+108
-8
lines changed

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,14 @@ aws-adfs integrates with:
253253
AWS_DEFAULT_REGION environmental variables
254254
instead of saving them to the aws
255255
configuration file.
256+
--print-console-signin-url Output a URL that lets users who sign in to
257+
your organization's network securely access
258+
the AWS Management Console.
259+
--console-role-arn TEXT Role to assume for use in conjunction with
260+
--print-console-signin-url
261+
--console-external-id TEXT External ID to pass in assume role for use
262+
in conjunction with --print-console-signin-
263+
url
256264
--role-arn TEXT Predefined role arn to selects, e.g. aws-
257265
adfs login --role-arn arn:aws:iam::123456789
258266
012:role/YourSpecialRole
@@ -420,4 +428,6 @@ poetry run pytest
420428
* [johan1252](https://github.com/johan1252) for: Ask for authentication method if there is no default method set in Duo Security settings
421429
* [pdecat](https://github.com/pdecat) for: Always return the same number of values from _initiate_authentication()
422430
* [mikereinhold](https://github.com/mikereinhold) for: Feature credential process
423-
* [pdecat](https://github.com/pdecat) for: Add --username-password-command command line parameter
431+
* [pdecat](https://github.com/pdecat) for:
432+
* Add --username-password-command command line parameter
433+
* Add --print-console-signin-url, --console-role-arn and --console-external-id command line parameters

aws_adfs/login.py

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from os import environ
1111
from platform import system
1212

13+
import boto3
1314
import botocore
1415
import botocore.exceptions
1516
import botocore.session
@@ -97,6 +98,14 @@
9798
is_flag=True,
9899
help='Output a URL that lets users who sign in to your organization\'s network securely access the AWS Management Console.',
99100
)
101+
@click.option(
102+
"--console-role-arn",
103+
help="Role to assume for use in conjunction with --print-console-signin-url",
104+
)
105+
@click.option(
106+
"--console-external-id",
107+
help="External ID to pass in assume role for use in conjunction with --print-console-signin-url",
108+
)
100109
@click.option(
101110
'--role-arn',
102111
help='Predefined role arn to selects, e.g. aws-adfs login --role-arn arn:aws:iam::123456789012:role/YourSpecialRole',
@@ -141,6 +150,8 @@ def login(
141150
stdout,
142151
printenv,
143152
print_console_signin_url,
153+
console_role_arn,
154+
console_external_id,
144155
role_arn,
145156
session_duration,
146157
no_session_cache,
@@ -269,7 +280,9 @@ def login(
269280
_emit_summary(config, aws_session_duration)
270281
_print_environment_variables(aws_session_token, config)
271282
elif print_console_signin_url:
272-
_print_console_signin_url(aws_session_token, adfs_host)
283+
_print_console_signin_url(
284+
aws_session_token, adfs_host, console_role_arn, console_external_id
285+
)
273286
else:
274287
_store(config, aws_session_token)
275288
_emit_summary(config, aws_session_duration)
@@ -300,9 +313,43 @@ def _print_environment_variables(aws_session_token, config):
300313
u"""{} AWS_DEFAULT_REGION={}""".format(envcommand, config.region))
301314

302315

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

321+
if console_role_arn:
322+
# Step 2: Using the access keys for an IAM user in your AWS account,
323+
# call "AssumeRole" to get temporary access keys for the federated user
324+
325+
# Note: Calls to AWS STS AssumeRole must be signed using the access key ID
326+
# and secret access key of an IAM user or using existing temporary credentials.
327+
# The credentials can be in EC2 instance metadata, in environment variables,
328+
# or in a configuration file, and will be discovered automatically by the
329+
# client('sts') function. For more information, see the Python SDK docs:
330+
# http://boto3.readthedocs.io/en/latest/reference/services/sts.html
331+
# http://boto3.readthedocs.io/en/latest/reference/services/sts.html#STS.Client.assume_role
332+
333+
# FIXME: use botocore instead of boto3: https://github.com/boto/botocore/blob/1.21.49/botocore/credentials.py#L766
334+
sts_connection = boto3.client(
335+
"sts",
336+
aws_access_key_id=aws_session_token["Credentials"]["AccessKeyId"],
337+
aws_secret_access_key=aws_session_token["Credentials"]["SecretAccessKey"],
338+
aws_session_token=aws_session_token["Credentials"]["SessionToken"],
339+
)
340+
341+
if console_external_id:
342+
aws_session_token = sts_connection.assume_role(
343+
RoleArn=console_role_arn,
344+
RoleSessionName="aws-adfs",
345+
ExternalId=console_external_id,
346+
)
347+
else:
348+
aws_session_token = sts_connection.assume_role(
349+
RoleArn=console_role_arn,
350+
RoleSessionName="aws-adfs",
351+
)
352+
306353
# Step 3: Format resulting temporary credentials into JSON
307354
url_credentials = {}
308355
url_credentials['sessionId'] = aws_session_token['Credentials']['AccessKeyId']
@@ -314,7 +361,11 @@ def _print_console_signin_url(aws_session_token, adfs_host):
314361
# the sign-in action request, a 12-hour session duration, and the JSON document with temporary credentials
315362
# as parameters.
316363
request_parameters = "?Action=getSigninToken"
317-
request_parameters += "&SessionDuration=43200"
364+
365+
# https://signin.aws.amazon.com/federation endpoint returns a HTTP/1.1 400 Bad Request error with AssumeRole credentials when SessionDuration is set
366+
if not console_role_arn:
367+
request_parameters += "&SessionDuration=43200"
368+
318369
request_parameters += "&Session=" + urllib.parse.quote_plus(json_string_with_temp_credentials)
319370
request_url = "https://signin.aws.amazon.com/federation" + request_parameters
320371
r = requests.get(request_url)

poetry.lock

Lines changed: 42 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ requests-kerberos = [
4242
requests-negotiate-sspi= [
4343
{ version = ">=0.3.4", markers = "platform_system == 'Windows'" },
4444
]
45+
boto3 = "^1.20.50"
4546

4647
[tool.poetry.dev-dependencies]
4748
coverage = "<4"

0 commit comments

Comments
 (0)