AWS SDK로 페더레이션 사용자를 위한 URL 구성

AWS SDK로 페더레이션 사용자를 위한 URL 구성 (AWS STS)

이 코드 예제에서는 AWS SDK로 AWS STS를 사용해 페더레이션 사용자가 AWS Management Console에 접근할 수 있는 URL을 구성하는 방법을 보여드려요.

출처: 문서

본문

다음 작업을 다루어요.

  • 현재 계정의 Amazon S3 리소스에 대한 읽기 전용 액세스를 부여하는 IAM 역할 생성
  • AWS 페더레이션 엔드포인트에서 보안 토큰 얻기
  • 페더레이션 자격 증명으로 콘솔에 접근할 수 있는 URL 구성

Python (SDK for Python / Boto3)

Note GitHub에 더 많은 내용이 있어요. AWS Code Examples Repository에서 전체 예제와 설정·실행 방법을 확인할 수 있어요.

현재 계정의 S3 리소스에 대한 읽기 전용 액세스를 부여하는 역할을 만들어요.

def setup(iam_resource):
	"""
	Creates a role that can be assumed by the current user.
	Attaches a policy that allows only Amazon S3 read-only access.

	:param iam_resource: A Boto3 AWS Identity and Access Management (IAM) instance
	that has the permission to create a role.
	:return: The newly created role.
	"""
	role = iam_resource.create_role(
		RoleName=unique_name("role"),
		AssumeRolePolicyDocument=json.dumps(
			{
				"Version":"2012-10-17",
				"Statement": [
					{
						"Effect": "Allow",
						"Principal": {"AWS": iam_resource.CurrentUser().arn},
						"Action": "sts:AssumeRole",
					}
				],
			}
		),
	)
	role.attach_policy(PolicyArn="arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess")
	print(f"Created role {role.name}.")

	print("Give AWS time to propagate these new resources and connections.", end="")
	progress_bar(10)

	return role

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.

	: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

데모용으로 만든 리소스를 삭제해요.

def teardown(role):
	"""
	Removes all resources created during setup.

	:param role: The demo role.
	"""
	for attached in role.attached_policies.all():
		role.detach_policy(PolicyArn=attached.arn)
		print(f"Detached {attached.policy_name}.")
	role.delete()
	print(f"Deleted {role.name}.")

앞서 정의한 함수들로 이 시나리오를 실행해요.

def usage_demo():
	"""Drives the demonstration."""
	print("-" * 88)
	print(f"Welcome to the AWS Security Token Service federated URL demo.")
	print("-" * 88)
	iam_resource = boto3.resource("iam")
	role = setup(iam_resource)
	sts_client = boto3.client("sts")
	try:
		federated_url = construct_federated_url(
			role.arn, "AssumeRoleDemoSession", "example.org", sts_client
		)
		print(
			"Constructed a federated URL that can be used to connect to the "
			"AWS Management Console with role-defined permissions:"
		)
		print("-" * 88)
		print(federated_url)
		print("-" * 88)
		_ = input(
			"Copy and paste the above URL into a browser to open the AWS "
			"Management Console with limited permissions. When done, press "
			"Enter to clean up and complete this demo."
		)
	finally:
		teardown(role)
	print("Thanks for watching!")

API 상세는 AssumeRole in AWS SDK for Python (Boto3) API Reference를 참고해요.

더 알아보기 (Learn more)