📝

URL だけで AWS にサインインしてみた

2025/01/12に公開

今のはスイッチロールではない…AssumeRole からのフェデレーションサインインだ…をやってみた | DevelopersIO
上記ブログを Python バージョンでやってみました。
実行環境は Cloud9 です。

コード

AWS コンソールへのカスタム ID ブローカーアクセスを有効にする - AWS Identity and Access Management
上記ドキュメントのコードのまま使用しました。

コード
import urllib, json, sys
import requests # 'pip install requests'
import boto3 # AWS SDK for Python (Boto3) 'pip install boto3'

# Step 1: Authenticate user in your own identity system.

# Step 2: Using the access keys for an IAM user in your AWS アカウント,
# 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 Amazon 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
sts_connection = boto3.client('sts')

assumed_role_object = sts_connection.assume_role(
    RoleArn="arn:aws:iam::account-id:role/ROLE-NAME",
    RoleSessionName="AssumeRoleSession",
)

# Step 3: Format resulting temporary credentials into JSON
url_credentials = {}
url_credentials['sessionId'] = assumed_role_object.get('Credentials').get('AccessKeyId')
url_credentials['sessionKey'] = assumed_role_object.get('Credentials').get('SecretAccessKey')
url_credentials['sessionToken'] = assumed_role_object.get('Credentials').get('SessionToken')
json_string_with_temp_credentials = json.dumps(url_credentials)

# Step 4. Make request to AWS federation endpoint to get sign-in token. Construct the parameter string with
# 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"
if sys.version_info[0] < 3:
    def quote_plus_function(s):
        return urllib.quote_plus(s)
else:
    def quote_plus_function(s):
        return urllib.parse.quote_plus(s)
request_parameters += "&Session=" + quote_plus_function(json_string_with_temp_credentials)
request_url = "https://signin.aws.amazon.com/federation" + request_parameters
r = requests.get(request_url)
# Returns a JSON document with a single element named SigninToken.
signin_token = json.loads(r.text)

# Step 5: Create URL where users can use the sign-in token to sign in to 
# the console. This URL must be used within 15 minutes after the
# sign-in token was issued.
request_parameters = "?Action=login" 
request_parameters += "&Issuer=Example.org" 
request_parameters += "&Destination=" + quote_plus_function("https://console.aws.amazon.com/")
request_parameters += "&SigninToken=" + signin_token["SigninToken"]
request_url = "https://signin.aws.amazon.com/federation" + request_parameters

# Send final URL to stdout
print (request_url)

必要な設定

  • Cloud9 環境の EC2 インスタンスに付与されている IAM ロールに AdministratorAccess 権限を付与
  • Cloud9 のマネージド一時認証を無効化
    • 設定 > AWS Settings > Credentials > AWS managed temporary credentials
  • AssumeRole 先の IAM ロールの信頼関係で AssumeRole 元のアカウントを許可
信頼ポリシー
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::012345678901:root"
			},
			"Action": "sts:AssumeRole"
		}
	]
}

Cloud9 でコード実行

上記コードを任意の名称の Python ファイルに保存し、Cloud9 の実行機能で実行します。

実行後に URL が表示されれば成功です。
この URL をシークレットウィンドウや別のブラウザで開くと、assumed_role_object で指定した IAM ロールの権限でコンソールにアクセスできます。

get-caller-identity コマンドの実行でも RoleSessionName に指定した AssumeRoleSession というセッション名でアクセスしていることを確認できます。

$ aws sts get-caller-identity
{
    "UserId": "xxx:AssumeRoleSession",
    "Account": "012345678901",
    "Arn": "arn:aws:sts::012345678901:assumed-role/xxx/AssumeRoleSession"
}

ユースケース

冒頭のブログで紹介されているケースが考えられます。

外部の人に一時的にコンソールを覗いてもらう、といった場面でも使えそうですね。

まとめ

今回は Python で生成した URL でのフェデレーションサインインを試してみました。
どなたかの参考になれば幸いです。

参考資料

Discussion