Do you guys use AWS in your business? It's very convenient because it supports AWS, infrastructure construction and operation. It's not just the infrastructure guys, but the features that benefit everyone who connects to the environment, like CloudWatch and Session Manager, are often released.
These great AWS features just benefit from infrastructure, and often don't reach consultants and product developers very often. The reason is that the number of people who can use the "management console" is limited. AWS is getting better and better, but it's a waste to have a limited number of people who can use it. On the other hand, it's hard to implement interfaces so that they can be used by various people, and it's also awkward to have to deal with each time AWS expands.
Why not make the "Management Console", the strongest interface that can access all the functions of AWS, available to "people who are not assigned AWS users"? This is the main subject of this article.
1.Amazon Cognito https://dev.classmethod.jp/cloud/aws/what-is-the-cognito/ Cognito is a user identity-themed service announced in July 2014. Read "Kogunito". Simply put, it is a function that can provide resources in AWS separately for each user, for example, you can create a file upload area dedicated to Mr. A.
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html#STSConsoleLink_programPython To give users who sign in to your organization's network secure access to the AWS Management Console, you can write and run code that generates a URL for it. This URL contains the sign-in token obtained from AWS and uses it to authenticate the user to AWS.
3.Python(boto3) Use a module called boto3 to operate AWS API with python. https://aws.amazon.com/jp/sdk-for-python/
You can use the Amazon Cognito ID Pool to identify AWS users who have policies with restricted access. They also have an access key that you can use to generate the login URL provided in Allowing Custom Identity Brokers to Access the AWS Console. To do this, we need to prepare some resources on the AWS account, so we will explain them as well.
Attach the AmazonCognitoPowerUser policy and the AmazonCognitoDeveloperAuthenticatedIdentities policy.
From the URL below, create an area called IDPool that stores user information. https://ap-northeast-1.console.aws.amazon.com/cognito/create/?region=ap-northeast-1# 1.Identity Pool Name = Give it any name you like.
Check "Enable Access to Unauthenticated Identities" to allow anonymous identities in Unauthenticated Identities. Since we will not explain the authentication logic this time, we will issue an access key without authentication.
When using an unauthenticated user, you cannot authorize the use of the management console without using the basic (classic) flow, so check "Allow basic (classic) flow".
Create a pool.
The page of Identify the IAM roles to use with your new identity pool will be displayed. Please display the details. (By the way, the top is the authenticated ID and the bottom is the guest ID setting)
Create a new role. You can change the authority for authenticated and unauthenticated, so create Unauth and Authed respectively. By the way, I don't plan to use Authed this time, so it doesn't matter if the contents are appropriate.
Attach ReadOnlyAccess and the following to Unauth. This time, let's make Session Manager an available guest role.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Cognito",
"Effect": "Allow",
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*",
"sts:GetFederationToken"
],
"Resource": [
"*"
]
},
{
"Sid": "Ssm",
"Effect": "Allow",
"Action": [
"ssmmessages:CreateDataChannel",
"s3:GetEncryptionConfiguration",
"ssm:UpdateInstanceInformation",
"ssmmessages:OpenDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:CreateControlChannel",
"ssm:StartSession"
],
"Resource": "*"
}
]
}
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html#STSConsoleLink_programPython
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#Execute as follows.
#python3 login_test.py user_name
import urllib, json, sys
import requests
import boto3
import datetime
_args = sys.argv
_USER = _args[1]
_AWS_ACCOUNT = "123456789012"
_CONV_AWS_ACCESS_KEY_ID = "ASIA*******:"
_CONV_AWS_SECRET_ACCESS_KEY = "**********"
_CONV_AWS_SESSION_TOKEN = "*********"
_REGION_NAME = "ap-northeast-1"
_ID_POOL_ID = "Use the one you noted in step 8."
_ARN = "arn:aws:cognito-identity:ap-northeast-1:123456789012:identitypool/ap-northeast-1:*******"
_ROLE_ARN = "arn:aws:iam::123456789012:role/Unauth"
class TestClass():
def cognito_auth(self):
try:
#Creating a client to operate cognit
cognito_client = boto3.client('cognito-identity',
region_name = _REGION_NAME,
aws_access_key_id = _CONV_AWS_ACCESS_KEY_ID,
aws_secret_access_key = _CONV_AWS_SECRET_ACCESS_KEY,
aws_session_token = _CONV_AWS_SESSION_TOKEN #Not needed if you're not using MFA
)
#ID acquisition
user_id = cognito_client.get_id(
AccountId = _AWS_ACCOUNT,
IdentityPoolId = _ID_POOL_ID
)["IdentityId"]
print("Cognito ID:"+user_id)
except:
raise Exception("get id faild.")
try:
#Role setting check
roles = cognito_client.get_identity_pool_roles(IdentityPoolId=_ID_POOL_ID)["Roles"]["unauthenticated"]
print("Use role:"+roles)
# GetOpenIdToken + AssumeRoleWithWebIdenity
token = cognito_client.get_open_id_token(
IdentityId=user_id
)
sts_client = boto3.client('sts',
region_name = _REGION_NAME,
aws_access_key_id = _CONV_AWS_ACCESS_KEY_ID,
aws_secret_access_key = _CONV_AWS_SECRET_ACCESS_KEY,
aws_session_token = _CONV_AWS_SESSION_TOKEN #Not needed if you're not using MFA
)
d_today = str(datetime.date.today())
credentials_for_identity = sts_client.assume_role_with_web_identity(
RoleArn = _ROLE_ARN,
RoleSessionName = _USER + "-" + d_today,#Character string at the beginning of the log Let's enter information that can identify who the session is.
WebIdentityToken = token["Token"]
)
AccessKeyId = credentials_for_identity["Credentials"]["AccessKeyId"]
SecretKey = credentials_for_identity["Credentials"]["SecretAccessKey"]
SessionToken = credentials_for_identity["Credentials"]["SessionToken"]
except:
#ID deletion
#If you make a mistake, delete the id you created in vain.
del_response = cognito_client.delete_identities(
IdentityIdsToDelete=[
user_id
]
)
raise Exception("cognito_auth faild.","delete id :"+str(del_response["ResponseMetadata"]["RequestId"]))
url_credentials = {}
url_credentials['sessionId'] = AccessKeyId
url_credentials['sessionKey'] = SecretKey
url_credentials['sessionToken'] = SessionToken
json_string_with_temp_credentials = json.dumps(url_credentials)
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)
def main(self):
print("success login! welcome "+_USER)
self.cognito_auth()
if __name__ == "__main__":
TC = TestClass()
TC.main()
login_test.py is implemented on the assumption that the user has been authenticated by the time it is executed. So, if you hit it by itself, an account will be issued and a very long login URL will be issued. When you access that URL, you will be redirected to the management console screen and you will be successfully federated. In addition to ReadOnly permissions, Session Manager also allows you to see which instances are standing from EC2 and use Session Manager to access your environment.
This time, we have made it possible for users who have not been issued AWS users to log in to the AWS Management Console. With this mechanism, IAM can manage accounts individually and provide a management console easily without the need for maintenance every time a retired employee leaves the company. Since AWS will strengthen the management console without permission, we will be able to continue to improve business efficiency without spending our development man-hours. It's very convenient, so please give it a try.
I am also a beginner on AWS (about cloud practitioner), so I would like to thank you for any suggestions, questions, or impressions. If you have any questions, please leave a comment.
Thank you for your hard work.