[PYTHON] Les utilisateurs sans compte accèdent à AWS Management Console

introduction

AWS est-il utilisé dans les affaires, tout le monde? C'est très pratique car il prend en charge diverses choses, de la construction d'AWS et de l'infrastructure à l'exploitation. Non seulement le personnel de l'infrastructure, mais également des fonctionnalités qui sont bénéfiques pour toutes les parties connectées à l'environnement, telles que CloudWatch et Session Manager, sont souvent publiées.

Au fait (soulever un problème)

Ces excellentes fonctionnalités AWS ne bénéficient que de l'infrastructure et ne parviennent souvent pas très souvent aux consultants et aux développeurs de produits. La raison en est que le nombre de personnes pouvant utiliser la "console de gestion" est limité. AWS améliore de plus en plus ses fonctionnalités, mais c'est un gaspillage d'avoir un nombre limité de personnes qui peuvent les utiliser. D'un autre côté, il est difficile d'implémenter des interfaces afin qu'elles puissent être utilisées par différentes personnes, et il est également difficile de devoir gérer chaque fois qu'AWS se développe.

Puis (solution)

Ne serait-il pas bien de rendre la "Management Console", l'interface la plus puissante pouvant accéder à toutes les fonctions d'AWS, accessible aux "personnes qui ne sont pas affectées aux utilisateurs AWS"? C'est le sujet principal de cet article.

Quoi utiliser cette fois

1.Amazon Cognito https://dev.classmethod.jp/cloud/aws/what-is-the-cognito/ Cognito est un service sur le thème de l'identité des utilisateurs annoncé en juillet 2014. Lisez "Kogunito". En termes simples, il s'agit d'une fonction qui peut fournir des ressources dans AWS séparément pour chaque utilisateur, par exemple, vous pouvez créer une zone de téléchargement de fichiers dédiée à M. A.

2. Autorisez les courtiers d'identité personnalisés à accéder à la console AWS

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html#STSConsoleLink_programPython Pour donner aux utilisateurs qui se connectent au réseau de votre organisation un accès sécurisé à AWS Management Console, vous pouvez écrire et exécuter du code qui génère une URL pour celle-ci. Cette URL contient le jeton de connexion obtenu auprès d'AWS et l'utilise pour authentifier l'utilisateur auprès d'AWS.

3.Python(boto3) Utilisez un module appelé boto3 pour faire fonctionner les API AWS avec python. https://aws.amazon.com/jp/sdk-for-python/

Comment utiliser (vue d'ensemble)

Vous pouvez utiliser le pool d'ID Amazon Cognito pour identifier les utilisateurs AWS qui ont des stratégies avec un accès restreint. Ils disposent également d'une clé d'accès que vous pouvez utiliser pour générer l'URL de connexion fournie dans Autoriser les courtiers d'identité personnalisés à accéder à la console AWS. Pour ce faire, nous devons préparer certaines ressources sur le compte AWS, nous allons donc les expliquer également.

Préparation des ressources AWS

1. Ajoutez l'accès à l'utilisateur utilisé pour exploiter les ressources AWS

Attachez la stratégie AmazonCognitoPowerUser et la stratégie AmazonCognitoDeveloperAuthenticatedIdentities.

2. Création d'un pool d'ID

image.png

À partir de l'URL suivante, créez une zone appelée IDPool pour stocker les informations utilisateur. https://ap-northeast-1.console.aws.amazon.com/cognito/create/?region=ap-northeast-1# 1.Identity Pool Name = Donnez-lui le nom de votre choix.

  1. Cochez «Activer l'accès aux identités non authentifiées» pour autoriser les identités anonymes dans les identités non authentifiées. Puisque nous n'expliquerons pas la logique d'authentification cette fois, nous émettrons une clé d'accès sans authentification.

  2. Lorsque vous utilisez un utilisateur non authentifié, vous ne pouvez pas autoriser l'utilisation de la console de gestion sans utiliser le flux de base (classique), cochez donc «Autoriser le flux de base (classique)».

  3. Créez une piscine.

  4. La page Identifier les rôles IAM à utiliser avec votre nouveau pool d'identités s'affiche. Veuillez afficher les détails. (À propos, le haut est l'ID authentifié et le bas est le paramètre d'ID d'invité) image.png

  5. Créez un nouveau rôle. Vous pouvez modifier les autorisations pour authentifié et non authentifié, donc créez respectivement Unauth et Authed. En passant, je ne prévois pas d'utiliser Authed cette fois, donc peu importe si le contenu est approprié.

  6. Attachez ReadOnlyAccess et les éléments suivants à Unauth. Cette fois, faisons de Session Manager un rôle d'invité disponible.



{
    "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": "*"
        }
    ]
}
		
  1. Notez l'ID du pool d'ID écrit dans l'exemple de code. image.png

Implémentation Python

1. Implémentez login_test.py en remplaçant la partie de configuration des informations d'identification par cognito du code Python suivant.

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 -*-

#Exécutez comme suit.
#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                 = "Utilisez celui que vous avez noté à l'étape 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:
            #Créer un client pour faire fonctionner 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 #Non requis si vous n'utilisez pas MFA
            )
            #Acquisition d'identité
            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:
            #Vérification des paramètres de rôle
            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 #Non requis si vous n'utilisez pas MFA
            )

            d_today = str(datetime.date.today())
            credentials_for_identity = sts_client.assume_role_with_web_identity(
                RoleArn = _ROLE_ARN,
                RoleSessionName = _USER + "-" + d_today,#Chaîne de caractères au début du journal Entrons les informations permettant d'identifier qui est la session.
                WebIdentityToken = token["Token"]
            )

            AccessKeyId = credentials_for_identity["Credentials"]["AccessKeyId"]
            SecretKey = credentials_for_identity["Credentials"]["SecretAccessKey"]
            SessionToken = credentials_for_identity["Credentials"]["SessionToken"]
        except:
            #Suppression d'identifiant
            #Si vous faites une erreur, supprimez l'identifiant que vous avez créé en 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()

2. Exécutez login_test.py.

image.png

image.png

login_test.py est implémenté en supposant que l'utilisateur a été authentifié au moment de son exécution. Donc, si vous le frappez seul, un compte sera émis et une très longue URL de connexion sera émise. Lorsque vous accédez à cette URL, vous serez redirigé vers l'écran de la console de gestion et la connexion fédérée réussira. En plus de ReadOnly, les autorisations autorisent également le gestionnaire de session, afin que vous puissiez voir quelle instance se trouve à partir d'EC2 et utiliser le gestionnaire de session pour accéder à l'environnement.

en conclusion

Cette fois, nous avons permis aux utilisateurs qui n'ont pas reçu d'utilisateurs AWS de se connecter à AWS Management Console. Grâce à ce mécanisme, IAM peut gérer les comptes individuellement et fournir une console de gestion facilement sans nécessiter de maintenance à chaque départ d'un employé retraité. Étant donné qu'AWS renforcera la console de gestion sans autorisation, nous pourrons continuer à améliorer l'efficacité commerciale sans dépenser nos efforts de développement. C'est très pratique, alors essayez-le.

Étant donné que je suis également un débutant d'AWS (à propos du praticien du cloud), je tiens à vous remercier pour vos suggestions, questions ou impressions. Si vous avez des questions, laissez un commentaire.

Je vous remercie pour votre travail acharné.

Recommended Posts

Les utilisateurs sans compte accèdent à AWS Management Console
Obtenez un jeton d'accès pour l'API Pocket
Obtenez AccessToken pour le compte de service avec le SDK Firebase Admin Python