カスタム ID ブローカーに対する AWS コンソールへのアクセスの許可 - AWS Identity and Access Management

カスタム ID ブローカーに対する AWS コンソールへのアクセスの許可

組織のネットワークにサインインするユーザーに対して AWS Management Console への安全なアクセスを許可するには、そのための URL を生成するコードを記述して実行できます。この URL は、AWS から取得したサインイントークンを含み、それを使って AWS に対してユーザーを認証します。結果のコンソールセッションには、フェデレーションに起因する明確な AccessKeyId が含まれる場合があります。関連する CloudTrail イベントを介したフェデレーションサインインのアクセスキーの使用状況を追跡するには、「AWS CloudTrail による IAM および AWS STS の API コールのログ記録」と「AWS Management Console サインインイベント」を参照してください。

注記

組織で、SAML と互換性のある ID プロバイダー (IdP) を使用している場合は、コードを記述せずにコンソールにアクセスできます。これは、Microsoft の Active Directory フェデレーションサービスやオープンソースの Shibboleth などのプロバイダーで機能します。詳細については、「SAML 2.0 フェデレーティッドユーザーが AWS Management Consoleにアクセス可能にする」を参照してください。

組織のユーザーによる AWS Management Console へのアクセスを許可するには、以下の手順を実行するカスタム ID ブローカーを作成できます。

  1. ユーザーがローカル ID システムによって認証されていることを確認する。

  2. AWS Security Token Service (AWS STS) の AssumeRole (推奨) または GetFederationToken API オペレーションを呼び出して、ユーザーの一時的セキュリティ認証情報を取得する。ロールを引き受ける別の方法については、「IAM ロールを使用する」を参照してください。セキュリティ認証情報を取得するときにオプションのセッションタグを渡す方法については、「AWS STS でのセッションタグの受け渡し」を参照してください。

    • AssumeRole* API オペレーションのいずれかを使用してロールの一時的なセキュリティ認証情報を取得した場合、この呼び出しに DurationSeconds パラメータを含めることができます。このパラメータは、ロールセッションの期間を 900 秒 (15 分) からそのロールの最大セッション期間設定まで指定します。AssumeRole* オペレーションで DurationSeconds を使用する場合、長期的な認証情報を持つ IAM ユーザーとして呼び出す必要があります。それ以外の場合は、ステップ 3 のフェデレーションエンドポイントへの呼び出しが失敗します。ロールの最大値を確認または変更する方法については、「ロールの最大セッション期間設定の表示」を参照してください。

    • GetFederationToken API オペレーションを使用して認証情報を取得するには、呼び出しに DurationSeconds パラメータを含めることができます。このパラメータは、ロールセッションの継続期間を指定します。値の範囲は 900 秒 (15 分) から 129,600 秒 (36 時間) です。この API コールは、IAM ユーザーの AWS 長期的セキュリティ認証情報を使用することでのみ行うことができます。AWS アカウントのルートユーザー 認証情報を使用してこれらの呼び出しを行うこともできますが、推奨されません。ルートユーザーとしてこの呼び出しを行うと、デフォルトのセッションの継続期間は 1 時間です。900 秒 (15 分) から最長 3,600 秒 (1 時間) までセッションを指定できます。

  3. AWS フェデレーションエンドポイントを呼び出し、一時的なセキュリティ認証情報を指定して、サインイントークンをリクエストする。

  4. トークンを含むコンソールの URL を生成する:

    • URL で AssumeRole* API オペレーションのいずれかを使用する場合、SessionDuration HTTP パラメータを含めることができます。このパラメータはコンソールセッションの継続期間を 900 秒 (15 分) から 43200 秒 (12 時間) までの間で指定します。

    • URL で GetFederationToken API オペレーションを使用する場合、DurationSeconds パラメータを含めることができます。このパラメータは、フェデレーテッドコンソールセッションの継続期間を指定します。値の範囲は 900 秒 (15 分) から 129,600 秒 (36 時間) です。

      注記
      • SessionDuration を使用して一時的な認証情報を取得した場合は、GetFederationToken HTTP パラメータを使用しないでください。オペレーションが失敗します。

      • 1 つのロールの認証情報を使用して別のロールを引き受けることは、ロールの連鎖と呼ばれます。ロールの連鎖を使用すると、新しい認証情報は最長期間である 1 時間に制限されます。ロールを使用して EC2 インスタンスで実行されるアプリケーションにアクセス許可を付与する場合、これらのアプリケーションにはこの制限が適用されません。

  5. URL をユーザーに渡すか、ユーザーに代わって URL を呼び出す。

フェデレーションエンドポイントによって渡される URL はその作成後から 15 分間、有効です。これは、URL に関連付けられた一時的セキュリティ認証情報の期間 (秒) とは異なります。これらの認証情報は、認証情報の作成時から、作成時に指定した期間だけ有効です。

重要

URL は、関連付けられた一時的セキュリティ認証情報でアクセス許可を有効にした場合、AWS Management Console を介した AWS リソースへのアクセスを許可することを忘れないでください。そのため、この URL は機密情報として扱う必要があります。例えば、SSL 接続による 302 HTTP レスポンスステータスコードを使用して、安全なリダイレクトによって URL を返すことをお勧めします。302 HTTP レスポンスステータスコードの詳細については、「​RFC 2616 セクション 10.3.3」を参照してください。

これらのタスクを完了するために、AWS Identity and Access Management (IAM) と AWS Security Token Service (AWS STS) のHTTPS クエリ API を使用できます。または、Java、Ruby、C# などのプログラミング言語を該当する AWS SDK と共に使用できます。これらの方法のそれぞれについて、以下のトピックで説明します。

フェデレーションユーザーに対して AWS Management Console への直接アクセスを許可する URL を作成できます。このタスクでは、IAM と AWS STS の HTTPS クエリ API を使用します。クエリリクエストの詳細については、「クエリリクエストを行う」を参照してください。

注記

以下の手順は、テキスト文字列の例を含んでいます。読みやすくするために、長い例の一部では改行が追加されています。これらの文字列をご自分で使用するときは、改行をすべて削除してください。

フェデレーティッドユーザーに AWS Management Console からリソースに対するアクセスを許可するには
  1. ID および認証システムでユーザーを認証します。

  2. ユーザーの一時的なセキュリティ認証情報を取得します。一時的な認証情報は、アクセスキー ID、シークレットアクセスキー、およびセッショントークンで構成されています。一時的な認証情報の作成方法の詳細については、「IAM の一時的な認証情報」を参照してください。

    一時的な認証情報を取得するには、AWS STS の AssumeRole API (推奨) または GetFederationToken API を呼び出します。これらの API オペレーションの違いの詳細については、AWS セキュリティブログの「AWS アカウントへのアクセスを安全に委任する API オプションの理解」を参照してください。

    重要

    GetFederationToken API を使用して一時的セキュリティ認証情報を作成する場合、ロールを引き受けるユーザーに認証情報を提供するアクセス許可を指定する必要があります。AssumeRole* で始まるいずれの API オペレーションでも、IAM ロールを使用してアクセス許可を割り当てます。その他の API オペレーションでは、この方法は API によって異なります。詳細については、「一時的なセキュリティ認証情報のアクセス権限を制御する」を参照してください。さらに、AssumeRole* API オペレーションを使用する場合、長期的な認証情報を使用する IAM ユーザーとして呼び出す必要があります。それ以外の場合は、ステップ 3 のフェデレーションエンドポイントへの呼び出しが失敗します。

  3. 一時的なセキュリティ認証情報を取得した後、この情報から JSON セッション文字列を生成して、サインイントークンに置き換えられるようにします。以下の例は、認証情報のエンコード方法を示しています。プレースホルダーテキストを、先ほどの手順で取得した認証情報の該当する値に置き換えます。

    {"sessionId":"*** temporary access key ID ***", "sessionKey":"*** temporary secret access key ***", "sessionToken":"*** session token ***"}
  4. 前の手順からのセッション文字列を URL エンコードします。エンコードする情報は機密であるため、このエンコードにウェブサービスを利用しないことをお勧めします。代わりに、開発ツールキットのローカルにインストールされた関数または機能を使用して、この情報を安全にエンコードします。Python では urllib.quote_plus 関数、Java では URLEncoder.encode 関数、Ruby では CGI.escape 関数を使用できます。このトピックの後の例を参照してください。

  5. 注記

    ここで AWS は POST リクエストをサポートします。

    最後に、フェデレーションユーザーが AWS Management Console へのアクセスに使用できる URL を作成します。URL は、「ステップ 5」で使用した同じフェデレーション URL エンドポイントに以下のパラメータを追加したものです。

    ?Action = login &Issuer = *** the form-urlencoded URL for your internal sign-in page *** &Destination = *** the form-urlencoded URL to the desired AWS console page *** &SigninToken = *** the value of SigninToken received in the previous step ***
    注記

    このステップの以下の手順は、GET API を使用する場合にのみ機能します。

    以下の例は、最終的な URL がどのようになるかを示します。URL は、作成時から 15 分間、有効です。URL 内に組み込まれた一時的なセキュリティ認証情報とコンソールセッションは、認証情報の初回リクエスト時に SessionDuration HTTP パラメータで指定した期間、有効です。

    https://signin.aws.amazon.com/federation ?Action=login &Issuer=https%3A%2F%2Fexample.com &Destination=https%3A%2F%2Fconsole.aws.amazon.com%2F &SigninToken=VCQgs5qZZt3Q6fn8Tr5EXAMPLEmLnwB7JjUc-SHwnUUWabcRdnWsi4DBn-dvC CZ85wrD0nmldUcZEXAMPLE-vXYH4Q__mleuF_W2BE5HYexbe9y4Of-kje53SsjNNecATfjIzpW1 WibbnH6YcYRiBoffZBGExbEXAMPLE5aiKX4THWjQKC6gg6alHu6JFrnOJoK3dtP6I9a6hi6yPgm iOkPZMmNGmhsvVxetKzr8mx3pxhHbMEXAMPLETv1pij0rok3IyCR2YVcIjqwfWv32HU2Xlj471u 3fU6uOfUComeKiqTGX974xzJOZbdmX_t_lLrhEXAMPLEDDIisSnyHGw2xaZZqudm4mo2uTDk9Pv 9l5K0ZCqIgEXAMPLEcA6tgLPykEWGUyH6BdSC6166n4M4JkXIQgac7_7821YqixsNxZ6rsrpzwf nQoS14O7R0eJCCJ684EXAMPLEZRdBNnuLbUYpz2Iw3vIN0tQgOujwnwydPscM9F7foaEK3jwMkg Apeb1-6L_OB12MZhuFxx55555EXAMPLEhyETEd4ZulKPdXHkgl6T9ZkIlHz2Uy1RUTUhhUxNtSQ nWc5xkbBoEcXqpoSIeK7yhje9Vzhd61AEXAMPLElbWeouACEMG6-Vd3dAgFYd6i5FYoyFrZLWvm 0LSG7RyYKeYN5VIzUk3YWQpyjP0RiT5KUrsUi-NEXAMPLExMOMdoODBEgKQsk-iu2ozh6r8bxwC RNhujg

以下の例は、Python を使用して、プログラムでフェデレーションユーザーに AWS Management Console への直接アクセスを許可する URL を作成する方法を示します。ここでは、以下の 2 つの例を示します。

  • GET リクエスト経由で AWS にフェデレートします

  • POST リクエスト経由で AWS にフェデレートします

どちらの例でも、AWS SDK for Python (Boto3)AssumeRole API を使用して、一時的なセキュリティ認証情報を取得します。

GET リクエストの使用

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)

POST リクエストの使用

import urllib, json, sys import requests # 'pip install requests' import boto3 # AWS SDK for Python (Boto3) 'pip install boto3' import os from selenium import webdriver # 'pip install selenium', 'brew install chromedriver' # Step 1: Authenticate user in your own identity system. # Step 2: Using the access keys for an IAM user in your AAWS アカウント, # 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 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) sts_connection = boto3.client('sts') assumed_role_object = sts_connection.assume_role( RoleArn="arn:aws:iam::account-id:role/ROLE-NAME", RoleSessionName="AssumeRoleDemoSession", ) # 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 = {} request_parameters['Action'] = 'getSigninToken' request_parameters['SessionDuration'] = '43200' request_parameters['Session'] = json_string_with_temp_credentials request_url = "https://signin.aws.amazon.com/federation" r = requests.post( request_url, data=request_parameters) # Returns a JSON document with a single element named SigninToken. signin_token = json.loads(r.text) # Step 5: Create a POST request where users can use the sign-in token to sign in to # the console. The POST request must be made within 15 minutes after the # sign-in token was issued. request_parameters = {} request_parameters['Action'] = 'login' request_parameters['Issuer']='Example.org' request_parameters['Destination'] = 'https://console.aws.amazon.com/' request_parameters['SigninToken'] =signin_token['SigninToken'] jsrequest = ''' var form = document.createElement('form'); form.method = 'POST'; form.action = '{request_url}'; request_parameters = {request_parameters} for (var param in request_parameters) {{ if (request_parameters.hasOwnProperty(param)) {{ const hiddenField = document.createElement('input'); hiddenField.type = 'hidden'; hiddenField.name = param; hiddenField.value = request_parameters[param]; form.appendChild(hiddenField); }} }} document.body.appendChild(form); form.submit(); '''.format(request_url=request_url, request_parameters=request_parameters) driver = webdriver.Chrome() driver.execute_script(jsrequest);

以下の例は、Java を使用して、プログラムでフェデレーションユーザーに AWS Management Console への直接アクセスを許可する URL を作成する方法を示します。以下のコード例では、AWS SDK for Java を使用しています。

import java.net.URLEncoder; import java.net.URL; import java.net.URLConnection; import java.io.BufferedReader; import java.io.InputStreamReader; // Available at http://www.json.org/java/index.html import org.json.JSONObject; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient; import com.amazonaws.services.securitytoken.model.Credentials; import com.amazonaws.services.securitytoken.model.GetFederationTokenRequest; import com.amazonaws.services.securitytoken.model.GetFederationTokenResult; /* Calls to AWS STS API operations must be signed using the access key ID and secret access key of an IAM user or using existing temporary credentials. The credentials should not be embedded in code. For this example, the code looks for the credentials in a standard configuration file. */ AWSCredentials credentials = new PropertiesCredentials( AwsConsoleApp.class.getResourceAsStream("AwsCredentials.properties")); AWSSecurityTokenServiceClient stsClient = new AWSSecurityTokenServiceClient(credentials); GetFederationTokenRequest getFederationTokenRequest = new GetFederationTokenRequest(); getFederationTokenRequest.setDurationSeconds(1800); getFederationTokenRequest.setName("UserName"); // A sample policy for accessing Amazon Simple Notification Service (Amazon SNS) in the console. String policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sns:*\"," + "\"Effect\":\"Allow\",\"Resource\":\"*\"}]}"; getFederationTokenRequest.setPolicy(policy); GetFederationTokenResult federationTokenResult = stsClient.getFederationToken(getFederationTokenRequest); Credentials federatedCredentials = federationTokenResult.getCredentials(); // The issuer parameter specifies your internal sign-in // page, for example https://mysignin.internal.mycompany.com/. // The console parameter specifies the URL to the destination console of the // AWS Management Console. This example goes to Amazon SNS. // The signin parameter is the URL to send the request to. String issuerURL = "https://mysignin.internal.mycompany.com/"; String consoleURL = "https://console.aws.amazon.com/sns"; String signInURL = "https://signin.aws.amazon.com/federation"; // Create the sign-in token using temporary credentials, // including the access key ID, secret access key, and session token. String sessionJson = String.format( "{\"%1$s\":\"%2$s\",\"%3$s\":\"%4$s\",\"%5$s\":\"%6$s\"}", "sessionId", federatedCredentials.getAccessKeyId(), "sessionKey", federatedCredentials.getSecretAccessKey(), "sessionToken", federatedCredentials.getSessionToken()); // Construct the sign-in request with the request sign-in token action, a // 12-hour console session duration, and the JSON document with temporary // credentials as parameters. String getSigninTokenURL = signInURL + "?Action=getSigninToken" + "&DurationSeconds=43200" + "&SessionType=json&Session=" + URLEncoder.encode(sessionJson,"UTF-8"); URL url = new URL(getSigninTokenURL); // Send the request to the AWS federation endpoint to get the sign-in token URLConnection conn = url.openConnection (); BufferedReader bufferReader = new BufferedReader(new InputStreamReader(conn.getInputStream())); String returnContent = bufferReader.readLine(); String signinToken = new JSONObject(returnContent).getString("SigninToken"); String signinTokenParameter = "&SigninToken=" + URLEncoder.encode(signinToken,"UTF-8"); // The issuer parameter is optional, but recommended. Use it to direct users // to your sign-in page when their session expires. String issuerParameter = "&Issuer=" + URLEncoder.encode(issuerURL, "UTF-8"); // Finally, present the completed URL for the AWS console session to the user String destinationParameter = "&Destination=" + URLEncoder.encode(consoleURL,"UTF-8"); String loginURL = signInURL + "?Action=login" + signinTokenParameter + issuerParameter + destinationParameter;

以下の例は、Ruby を使用して、プログラムでフェデレーションユーザーに AWS Management Console への直接アクセスを許可する URL を作成する方法を示します。このコード例では、AWS SDK for Ruby を使用しています。

require 'rubygems' require 'json' require 'open-uri' require 'cgi' require 'aws-sdk' # Create a new STS instance # # Note: Calls to AWS STS API operations must be signed using an access key ID # and secret access key. The credentials can be in EC2 instance metadata # or in environment variables and will be automatically discovered by # the default credentials provider in the AWS Ruby SDK. sts = Aws::STS::Client.new() # The following call creates a temporary session that returns # temporary security credentials and a session token. # The policy grants permissions to work # in the AWS SNS console. session = sts.get_federation_token({ duration_seconds: 1800, name: "UserName", policy: "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"sns:*\",\"Resource\":\"*\"}}", }) # The issuer value is the URL where users are directed (such as # to your internal sign-in page) when their session expires. # # The console value specifies the URL to the destination console. # This example goes to the Amazon SNS console. # # The sign-in value is the URL of the AWS STS federation endpoint. issuer_url = "https://mysignin.internal.mycompany.com/" console_url = "https://console.aws.amazon.com/sns" signin_url = "https://signin.aws.amazon.com/federation" # Create a block of JSON that contains the temporary credentials # (including the access key ID, secret access key, and session token). session_json = { :sessionId => session.credentials[:access_key_id], :sessionKey => session.credentials[:secret_access_key], :sessionToken => session.credentials[:session_token] }.to_json # Call the federation endpoint, passing the parameters # created earlier and the session information as a JSON block. # The request returns a sign-in token that's valid for 15 minutes. # Signing in to the console with the token creates a session # that is valid for 12 hours. get_signin_token_url = signin_url + "?Action=getSigninToken" + "&SessionType=json&Session=" + CGI.escape(session_json) returned_content = URI.parse(get_signin_token_url).read # Extract the sign-in token from the information returned # by the federation endpoint. signin_token = JSON.parse(returned_content)['SigninToken'] signin_token_param = "&SigninToken=" + CGI.escape(signin_token) # Create the URL to give to the user, which includes the # sign-in token and the URL of the console to open. # The "issuer" parameter is optional but recommended. issuer_param = "&Issuer=" + CGI.escape(issuer_url) destination_param = "&Destination=" + CGI.escape(console_url) login_url = signin_url + "?Action=login" + signin_token_param + issuer_param + destination_param