Habilitar o acesso do intermediador de identidades personalizado ao console da AWS - AWS Identity and Access Management

Habilitar o acesso do intermediador de identidades personalizado ao console da AWS

Você pode escrever e executar um código para criar um URL que permita que os usuários que façam login na rede de sua organização acessem com segurança o AWS Management Console. O URL inclui um token de login que você obtém da AWS e que autentica o usuário na AWS. A sessão de console resultante pode incluir um AccessKeyId diferente devido à federação. Para rastrear o uso da chave de acesso para o login da federação por meio de eventos relacionados do CloudTrail, consulte Registro em log de chamadas de API do IAM e do AWS STS com o AWS CloudTrail e Eventos de login do AWS Management Console.

nota

Se sua organização usa um provedor de identidade (IdP) que é compatível com SAML, é possível configurar o acesso ao console sem escrever código. Isso funciona com fornecedores como o Microsoft Active Directory Federation Services ou o Shibboleth de código aberto. Para obter detalhes, consulte Habilitar o acesso de usuários federados SAML 2.0 ao AWS Management Console.

Para permitir que os usuários de sua organização acessem o AWS Management Console, você pode criar um intermediador de identidades personalizado que executa as seguintes etapas:

  1. Verificar se o usuário está autenticado pelo seu sistema de identidades local.

  2. Chame as operações de API do AWS Security Token Service (AWS STS) AssumeRole (recomendado) ou GetFederationToken para obter credenciais de segurança temporárias para o usuário. Para saber mais sobre os diferentes métodos que você pode usar para assumir uma função, consulte Métodos para assumir um perfil. Para saber como passar tags de sessão opcionais ao obter suas credenciais de segurança, consulte Passar tags de sessão no AWS STS.

    • Se você usar uma das operações de API AssumeRole* para obter as credenciais de segurança temporárias para uma função, poderá incluir o parâmetro DurationSeconds na chamada. Esse parâmetro especifica a duração da sessão da função de 900 segundos (15 minutos) até o valor configurado de duração máxima da sessão para a função. Ao usar DurationSeconds em uma operação AssumeRole*, você deve chamá-la como um usuário do IAM com credenciais de longo prazo. Caso contrário, a chamada para o endpoint de federação na etapa 3 falhará. Para saber como visualizar ou alterar o valor máximo de uma função, consulte Atualizar a duração máxima da sessão de um perfil.

    • Se você usar a operação de API GetFederationToken para obter as credenciais, poderá incluir o parâmetro DurationSeconds na chamada. Esse parâmetro especifica a duração da sessão da função. O valor pode variar de 900 segundos (15 minutos) a 129.600 segundos (36 horas). Você só pode fazer essa chamada de API usando as credenciais de segurança da AWS de longo prazo de um usuário do IAM. Você também pode fazer essas chamadas usando credenciais de Usuário raiz da conta da AWS, mas isso não é recomendado. Se você fizer essa chamada como usuário raiz, a sessão padrão durará por uma hora. Ou você pode especificar uma sessão de 900 segundos (15 minutos) até 3.600 segundos (uma hora).

  3. Chamar o endpoint de federação da AWS e fornecer as credenciais de segurança temporárias para solicitar um token de login.

  4. Construir um URL para o console que inclui o token:

    • Se você usar uma das operações da API AssumeRole* em seu URL, poderá incluir o parâmetro HTTP SessionDuration. Esse parâmetro especifica a duração da sessão do console de 900 segundos (15 minutos) a 43.200 segundos (12 horas).

    • Se você usar a operação de API GetFederationToken em seu URL, poderá incluir o parâmetro DurationSeconds. Esse parâmetro especifica a duração da sessão do console federado. O valor pode variar de 900 segundos (15 minutos) a 129.600 segundos (36 horas).

      nota
      • Não use o parâmetro HTTP SessionDuration se você obteve suas credenciais temporárias com GetFederationToken. Isso fará com que a operação falhe.

      • O uso de credenciais de uma função para assumir outra função é chamado de encadeamento de funções. Quando você usa o encadeamento de funções, suas novas credenciais são limitadas a uma duração máxima de uma hora. Quando você usa funções para conceder permissões a aplicativos executados em instâncias do EC2, esses aplicativos não estão sujeitos a essa limitação.

  5. Fornecer o URL para o usuário ou invocar o URL em nome do usuário.

O URL que o endpoint de federação fornece é válido por 15 minutos após sua criação. Esse valor é diferente da duração (em segundos) da sessão com credenciais de segurança temporárias que é associada ao URL. Essas credenciais são válidas pela duração especificada quando você as criou, a partir do momento em que elas foram criadas.

Importante

O URL concede acesso aos seus recursos da AWS por meio do AWS Management Console se você habilitou permissões nas credenciais de segurança temporárias associadas. Por esse motivo, você deve tratar o URL como um segredo. Recomendamos o retorno do URL através de um redirecionamento seguro, por exemplo, usando um código de status de resposta HTTP 302 por meio de uma conexão SSL. Para obter mais informações sobre o código de status de resposta HTTP 302, consulte RFC 2616, seção 10.3.3.

Para concluir essas tarefas, você pode usar a API de consulta HTTPS para o AWS Identity and Access Management (IAM) e o AWS Security Token Service (AWS STS). Ou então, use linguagens de programação, como Java, Ruby ou C#, juntamente com o SDK da AWS. Cada um desses métodos é descrito nos tópicos a seguir.

Você pode construir um URL que ofereça aos seus usuários federados acesso direto ao AWS Management Console. Esta tarefa usa a API de consulta HTTPS do IAM e do AWS STS. Para obter mais informações sobre como fazer solicitações de consulta, consulte Como fazer solicitações de consulta.

nota

O procedimento a seguir contém exemplos de strings de texto. Para melhorar a legibilidade, quebras de linha foram adicionadas em alguns dos exemplos mais longos. Quando você criar estas strings para seu próprio uso, você deve omitir as quebras de linha.

Para dar a um usuário federado acesso aos seus recursos a partir do AWS Management Console
  1. Autentique o usuário em seu sistema de identidades e autorização.

  2. Obtenha credenciais de segurança temporárias para o usuário. As credenciais de segurança temporárias consistem em um ID de chave de acesso, uma chave de acesso secreta e um token de sessão. Para obter mais informações sobre a criação de credenciais de segurança temporárias, consulte Credenciais de segurança temporárias no IAM.

    Para obter credenciais temporárias, você pode chamar a API AssumeRole (recomendado) ou a API GetFederationToken do AWS STS. Para obter mais informações sobre as diferenças entre essas operações de API, consulte Compreenda as opções de API para delegação segura de acesso à sua conta da AWS no blog de segurança da AWS.

    Importante

    Quando você usa a API GetFederationToken para criar credenciais de segurança temporárias, deve especificar as permissões que as credenciais vão conceder ao usuário que assume a função. Para qualquer uma das operações de API que começam com AssumeRole*, você usa uma função do IAM para atribuir permissões. Para as outras operações de API, o mecanismo varia de acordo com a API. Para obter mais detalhes, consulte Permissões de credenciais de segurança temporárias. Além disso, se você usar as operações de API AssumeRole*, deverá chamá-las como um usuário do IAM com credenciais de longo prazo. Caso contrário, a chamada para o endpoint de federação na etapa 3 falhará.

  3. Depois que você obter as credenciais de segurança temporárias, incorpore as credenciais em uma string de sessão JSON para trocá-las por um token de login. O exemplo a seguir mostra como codificar as credenciais. Substitua o espaço reservado para texto pelos valores apropriados das credenciais que você recebeu na etapa anterior.

    {"sessionId":"*** temporary access key ID ***", "sessionKey":"*** temporary secret access key ***", "sessionToken":"*** session token ***"}
  4. Codifique por URL a string da sessão da etapa anterior. Como as informações que você está codificando são confidenciais, recomendamos que você evite usar um serviço da web para esta codificação. Em vez disso, use uma função ou recurso instalado localmente em seu toolkit de desenvolvimento para codificar essas informações com segurança. Você pode usar a função urllib.quote_plus em Python, a função URLEncoder.encode em Java ou a função CGI.escape em Ruby. Veja os exemplos mais adiante neste tópico.

  5. nota

    A AWS é compatível com solicitações POST aqui.

    Finalmente, crie o URL que seus usuários federados podem usar para acessar o AWS Management Console. O URL é o mesmo URL do endpoint de federação usado em Passo 5, mais os seguintes parâmetros:

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

    As instruções a seguir nesta etapa só funcionam usando a API GET.

    O exemplo a seguir mostra a possível aparência do URL final. O URL é válido por 15 minutos a partir do momento em que ele é criada. As credenciais de segurança temporárias e a sessão do console incorporada dentro do URL são válidas durante o período especificado no parâmetro HTTP SessionDuration quando você inicialmente as solicita.

    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

Os exemplos a seguir mostram como usar o Python para construir programaticamente uma URL que ofereça aos usuários federados acesso direto ao AWS Management Console. Veja dois exemplos a seguir:

  • Federar por meio de solicitações GET à AWS

  • Federar por meio de solicitações POST à AWS

Ambos os exemplos usam AWS SDK for Python (Boto3) e a API AssumeRole para obter credenciais de segurança temporárias.

Usar solicitações 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 Conta da 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)

Usar solicitações 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 AConta da 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 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);

O exemplo a seguir mostra como usar Java para programaticamente construir um URL que oferece aos usuários federados acesso direto ao AWS Management Console. O trecho de código a seguir usa o 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;

O exemplo a seguir mostra como usar Ruby para programaticamente construir um URL que oferece aos usuários federados acesso direto ao AWS Management Console. Esse trecho de código usa o 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