def _create_s3_client(self, loc): """Create a client object to use when connecting to S3. :param loc: `glance_store.location.Location` object, supplied from glance_store.location.get_location_from_uri() :returns: An object with credentials to connect to S3 """ s3_host = self._option_get('s3_store_host') url_format = self._option_get('s3_store_bucket_url_format') calling_format = {'addressing_style': url_format} session = boto_session.Session(aws_access_key_id=loc.accesskey, aws_secret_access_key=loc.secretkey) config = boto_client.Config(s3=calling_format) location = get_s3_location(s3_host) bucket_name = loc.bucket if (url_format == 'virtual' and not boto_utils.check_dns_name(bucket_name)): raise boto_exceptions.InvalidDNSNameError(bucket_name=bucket_name) region_name, endpoint_url = None, None if location: region_name = location else: endpoint_url = s3_host return session.client(service_name='s3', endpoint_url=endpoint_url, region_name=region_name, use_ssl=(loc.scheme == 's3+https'), config=config)
def __init__(self, buckets_info): boto_config = client.Config( connect_timeout=self.BOTO_TIMEOUT, read_timeout=self.BOTO_TIMEOUT ) self._s3_client = boto3.resource('s3', config=boto_config) self._buckets_info = buckets_info
def test_create_client_with_merging_client_configs(self, client_creator): config = client.Config(region_name='us-west-2') other_config = client.Config(region_name='us-east-1') self.session.set_default_client_config(config) self.session.create_client('sts', config=other_config) # Grab the client config used in creating the client used_client_config = ( client_creator.return_value.create_client.call_args[1][ 'client_config']) # Check that the client configs were merged self.assertEqual(used_client_config.region_name, 'us-east-1') # Make sure that the client config used is not the default client # config or the one passed in. It should be a new config. self.assertIsNot(used_client_config, config) self.assertIsNot(used_client_config, other_config)
def assume_role(cls, role_arn, principal_arn, saml_response, duration=3600): ''' Assumes the desired role using the saml_response given. The response should be b64 encoded. Duration is in seconds :param role_arn: role amazon resource name :param principal_arn: principal name :param saml_response: SAML object to assume role with :param duration: session duration (default: 3600) :return: AWS session token ''' # Assume role with new SAML conn = boto3.client('sts', config=client.Config( signature_version=botocore.UNSIGNED, user_agent=cls.USER_AGENT, region_name=None)) aws_session_token = conn.assume_role_with_saml( RoleArn=role_arn, PrincipalArn=principal_arn, SAMLAssertion=saml_response, DurationSeconds=duration, ) return aws_session_token
def default_config(timeout=BOTO_TIMEOUT, region=REGION): return client.Config( connect_timeout=timeout, read_timeout=timeout, region_name=region if region else REGION # Ensure region is never empty )
def test_client_with_custom_read_timeout(self): self.create_client_creator().create_client( 'myservice', 'us-west-2', client_config=client.Config(read_timeout=234)) call_kwargs = self.endpoint_creator.create_endpoint.call_args[1] self.assertEqual(call_kwargs['timeout'], (DEFAULT_TIMEOUT, 234))
def __init__(self, config): """ :param config: be complied with cup.util.conf.Configure2Dict().get_dict(). Shoule be dict like object :raise: cup.err.ConfigError if there's any config item missing """ ObjectInterface.__init__(self, config) required_keys = ['ak', 'sk', 'endpoint', 'bucket'] if not self._validate_config(config, required_keys): raise err.ConfigError(str(required_keys)) self._config = config self._ak = self._config['ak'] self._sk = self._config['sk'] self._endpoint = self._config['endpoint'] self._bucket = self._config['bucket'] import boto3 from botocore import exceptions from botocore import client as coreclient self._s3_config = coreclient.Config(signature_version='s3v4', s3={'addressing_style': 'path'}) logging.getLogger('boto3').setLevel(logging.INFO) logging.getLogger('botocore').setLevel(logging.INFO) logging.getLogger('s3transfer').setLevel(logging.INFO) log.info('to connect to boto3') self.__s3conn = boto3.client( 's3', aws_access_key_id=self._ak, aws_secret_access_key=self._sk, endpoint_url=self._endpoint, # region_name=conf_dict['region_name'], config=self._s3_config) self._exception = exceptions.ClientError
def test_client_region_overrides_region_from_client_config(self): client_config = client.Config() client_config.region_name = 'us-west-1' creator = self.create_client_creator() service_client = creator.create_client('myservice', 'us-west-2', client_config=client_config) self.assertEqual(service_client.meta.region_name, 'us-west-2')
def test_client_with_custom_both_timeout(self): self.create_client_creator().create_client('myservice', 'us-west-2', client_config=client.Config( connect_timeout=123, read_timeout=234)) call_kwargs = self.endpoint_creator.create_endpoint.call_args[1] self.assertEqual(call_kwargs['timeout'], (123, 234))
def test_create_client_with_default_client_config(self, client_creator): config = client.Config() self.session.set_default_client_config(config) self.session.create_client('sts') client_creator.return_value.create_client.assert_called_with( mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, scoped_config=mock.ANY, client_config=config, api_version=mock.ANY)
def assume_role(account_role, samlAssertion, sessionDuration): conn = boto3.client('sts', config=client.Config(signature_version=botocore.UNSIGNED)) aws_session_token = conn.assume_role_with_saml( RoleArn=account_role.role_arn, PrincipalArn=account_role.principal_arn, SAMLAssertion=samlAssertion, DurationSeconds=sessionDuration ) return aws_session_token
def test_config_passed_to_client_creator(self, client_creator): # Make sure there is no default set self.assertEqual(self.session.get_default_client_config(), None) # The config passed to the client should be the one that is used # in creating the client. config = client.Config(region_name='us-west-2') self.session.create_client('sts', config=config) client_creator.return_value.create_client.assert_called_with( mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, scoped_config=mock.ANY, client_config=config, api_version=mock.ANY)
def test_config_passed_to_client_creator(self, client_creator): config = client.Config() self.session.create_client('sts', config=config) client_creator.return_value.create_client.assert_called_with( mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY, scoped_config=mock.ANY, client_config=config)
def __init__(self, region, firehose_config=None, log_sources=None): boto_config = client.Config( connect_timeout=self.BOTO_TIMEOUT, read_timeout=self.BOTO_TIMEOUT, region_name=region ) self._client = boto3.client('firehose', config=boto_config) # Create a dictionary to hold parsed payloads by log type. # Firehose needs this information to send to its corresponding # delivery stream. self._categorized_payloads = defaultdict(list) self.load_enabled_log_sources(firehose_config, log_sources, force_load=True)
def _make_boto3_kinesis_client(container): region = container.get_parameter('aws_region') logger = container.get('logger') config = botocore_client.Config(connect_timeout=5, read_timeout=5, region_name=region) session_kwargs = {} try: session = boto3.Session(**session_kwargs) return session.client('kinesis', config=config) except ProfileNotFound: logger.error('AWS Kinesis Connection via Profile Failed')
def test_create_client_with_region_and_client_config(self): config = client.Config() # Use a client config with no region configured. ec2_client = self.session.create_client('ec2', region_name='us-west-2', config=config) self.assertEqual(ec2_client.meta.region_name, 'us-west-2') # If the region name is changed, it should not change the # region of the client config.region_name = 'us-east-1' self.assertEqual(ec2_client.meta.region_name, 'us-west-2') # Now make a new client with the updated client config. ec2_client = self.session.create_client('ec2', config=config) self.assertEqual(ec2_client.meta.region_name, 'us-east-1')
def _get_parameters(cls, *names): """Simple helper function to house the boto3 ssm client get_parameters operations Args: names (list): A list of parameter names to retrieve from the aws ssm parameter store Returns: tuple (dict, list): Dictionary with the load parameter names as keys and the actual parameter (as a dictionary) as the value. The seconary list that is returned contains any invalid parameters that were not loaded """ # Create the ssm boto3 client that will be cached and used throughout this execution # if one does not exist already if AppConfig.SSM_CLIENT is None: boto_config = client.Config(connect_timeout=cls.BOTO_TIMEOUT, read_timeout=cls.BOTO_TIMEOUT) AppConfig.SSM_CLIENT = boto3.client('ssm', config=boto_config) LOGGER.debug('Retrieving values from parameter store with names: %s', ', '.join('\'{}\''.format(name) for name in names)) try: parameters = AppConfig.SSM_CLIENT.get_parameters( Names=list(names), WithDecryption=True) except ClientError as err: joined_names = ', '.join('\'{}\''.format(name) for name in names) raise AppConfigError( 'Could not get parameter with names {}. Error: ' '{}'.format(joined_names, err.response['Error']['Message'])) decoded_params = {} for param in parameters['Parameters']: try: decoded_params[param['Name']] = json.loads(param['Value']) except ValueError: raise AppConfigError( 'Could not load value for parameter with ' 'name \'{}\'. The value is not valid json: ' '\'{}\''.format(param['Name'], param['Value'])) return decoded_params, parameters['InvalidParameters']
def login(profile, region, ssl_verification, adfs_ca_bundle, adfs_host, output_format, provider_id, s3_signature_version, env, stdin, authfile, stdout, printenv, role_arn, session_duration, assertfile, sspi, u2f_trigger_default, username, password): """ Authenticates an user with active directory credentials """ config = prepare.get_prepared_config( profile, region, ssl_verification, adfs_ca_bundle, adfs_host, output_format, provider_id, s3_signature_version, session_duration, sspi, u2f_trigger_default, ) _verification_checks(config) # Try re-authenticating using an existing ADFS session if username != None and password != None: #print(username) #print(password) #exit(0) principal_roles, assertion, aws_session_duration = authenticator.authenticate( config, username=username, password=password, assertfile=assertfile) else: principal_roles, assertion, aws_session_duration = authenticator.authenticate( config, assertfile=assertfile) #principal_roles, assertion, aws_session_duration = authenticator.authenticate(config, assertfile=assertfile) # If we fail to get an assertion, prompt for credentials and try again if assertion is None: password = None if stdin: config.adfs_user, password = _stdin_user_credentials() elif env: config.adfs_user, password = _env_user_credentials() elif authfile: config.adfs_user, password = _file_user_credentials( config.profile, authfile) if not config.adfs_user: config.adfs_user = click.prompt(text='Username', type=str, default=config.adfs_user) if not password: password = click.prompt('Password', type=str, hide_input=True) principal_roles, assertion, aws_session_duration = authenticator.authenticate( config, config.adfs_user, password) password = '******' del password if (role_arn is not None): config.role_arn = role_arn principal_arn, config.role_arn = role_chooser.choose_role_to_assume( config, principal_roles) if principal_arn is None or config.role_arn is None: click.echo('This account does not have access to any roles', err=True) exit(-1) # Use the assertion to get an AWS STS token using Assume Role with SAML # according to the documentation: # http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_assertions.html # This element contains one AttributeValue element that specifies the maximum time that the user # can access the AWS Management Console before having to request new temporary credentials. # The value is an integer representing the number of seconds, and can be # a maximum of 43200 seconds (12 hours). If this attribute is not present, # then the maximum session duration defaults to one hour # (the default value of the DurationSeconds parameter of the AssumeRoleWithSAML API). # To use this attribute, you must configure the SAML provider to provide single sign-on access # to the AWS Management Console through the console sign-in web endpoint at # https://signin.aws.amazon.com/saml. # Note that this attribute extends sessions only to the AWS Management Console. # It cannot extend the lifetime of other credentials. # However, if it is present in an AssumeRoleWithSAML API call, # it can be used to shorten the lifetime of the credentials returned by the call to less than # the default of 60 minutes. # # Note, too, that if a SessionNotOnOrAfter attribute is also defined, # then the lesser value of the two attributes, SessionDuration or SessionNotOnOrAfter, # establishes the maximum duration of the console session. try: session = botocore.session.get_session() session.set_config_variable('profile', config.profile) conn = session.create_client( 'sts', config=client.Config(signature_version=botocore.UNSIGNED)) except botocore.exceptions.ProfileNotFound: logging.debug('Profile {} does not exist yet'.format(config.profile)) session = botocore.session.get_session() conn = session.create_client( 'sts', config=client.Config(signature_version=botocore.UNSIGNED)) aws_session_token = conn.assume_role_with_saml( RoleArn=config.role_arn, PrincipalArn=principal_arn, SAMLAssertion=assertion, DurationSeconds=int(config.session_duration), ) if stdout: _emit_json(aws_session_token) elif printenv: _emit_summary(config, aws_session_duration) _print_environment_variables(aws_session_token, config) else: _store(config, aws_session_token) _emit_summary(config, aws_session_duration)
def default_config(timeout=BOTO_TIMEOUT, region=REGION): return client.Config(connect_timeout=timeout, read_timeout=timeout, region_name=region)
def load_config(cls, context, event): """Load the configuration for this app invocation Args: context (LambdaContext): The AWS LambdaContext object, passed in via the handler. Returns: AppConfig: Subclassed dictionary with the below structure that contains all of the methods for configuration validation, updating, saving, etc: { 'type': <type>, 'cluster': <cluster>, 'prefix': <prefix>, 'app_name': <app_name>, 'schedule_expression': <rate_interval>, 'region': <aws_region>, 'account_id': <aws_account_id>, 'function_name': <function_name>, 'qualifier': <qualifier>, 'last_timestamp': <time>, 'current_state': <running|succeeded|failed>, 'auth': { 'req_auth_item_01': <req_auth_value_01> } } """ # Load the base config from the context that will get updated with other info base_config = AppConfig._parse_context(context) LOGGER.debug('Loaded env config: %s', base_config) # Create the ssm boto3 client that will be cached and used throughout this execution # if one does not exist already if AppConfig.SSM_CLIENT is None: boto_config = client.Config( connect_timeout=cls.BOTO_TIMEOUT, read_timeout=cls.BOTO_TIMEOUT, region_name=base_config['region'] ) AppConfig.SSM_CLIENT = boto3.client('ssm', config=boto_config) # Generate a map of all the suffixes and full parameter names param_names = {key: '_'.join([base_config['function_name'], key]) for key in {cls.AUTH_CONFIG_SUFFIX, cls.BASE_CONFIG_SUFFIX, cls.STATE_CONFIG_SUFFIX}} LOGGER.debug('Parameter suffixes and names: %s', param_names) # Get the loaded parameters and a list of any invalid ones from parameter store params, invalid_params = AppConfig._get_parameters(param_names.values()) LOGGER.debug('Retrieved parameters from parameter store: %s', cls._scrub_auth_info(params, param_names[cls.AUTH_CONFIG_SUFFIX])) LOGGER.debug('Invalid parameters could not be retrieved from parameter store: %s', invalid_params) # Check to see if there are any required parameters in the invalid params list missing_required_params = [param for param in invalid_params if param != param_names[cls.STATE_CONFIG_SUFFIX]] if missing_required_params: joined_params = ', '.join('\'{}\''.format(param) for param in missing_required_params) raise AppIntegrationConfigError('Could not load parameters required for this ' 'configuration: {}'.format(joined_params)) # Update the env config with the base config values base_config.update(params[param_names[cls.BASE_CONFIG_SUFFIX]]) # The state config can be None with first time deploys, so us a lookup and # add default empty values if there is no state found base_config.update(params.get(param_names[cls.STATE_CONFIG_SUFFIX], {cls._STATE_KEY: None, cls._TIME_KEY: None})) # Add the auth config info to the 'auth' key since these key/values can vary # from service to service base_config[cls.AUTH_CONFIG_SUFFIX] = { key: value.encode('utf-8') if isinstance(value, unicode) else value for key, value in params[param_names[cls.AUTH_CONFIG_SUFFIX]].iteritems() } return AppConfig(base_config, event)
def login(profile, region, ssl_verification, adfs_ca_bundle, adfs_host, adfs_user, output_format, provider_id, s3_signature_version, env, stdin, authfile, use_keychain, role_chaining_role_arn, stdout, printenv, role_arn, session_duration, assertfile, sspi, u2f_trigger_default, prompt): """ Authenticates an user with active directory credentials """ config = prepare.get_prepared_config( profile, region, ssl_verification, adfs_ca_bundle, adfs_host, output_format, provider_id, s3_signature_version, session_duration, sspi, u2f_trigger_default, role_chaining_role_arn, ) _verification_checks(config) # Try re-authenticating using an existing ADFS session principal_roles, assertion, aws_session_duration = authenticator.authenticate( config, assertfile=assertfile) # If we fail to get an assertion, prompt for credentials and try again if assertion is None: password = None if stdin: config.adfs_user, password = _stdin_user_credentials() elif env: config.adfs_user, password = _env_user_credentials() elif authfile: config.adfs_user, password = _file_user_credentials( config.profile, authfile) if not config.adfs_user and use_keychain is None: config.adfs_user = adfs_user if adfs_user else click.prompt( text='Username', type=str, default=config.adfs_user) if use_keychain: config.adfs_user, password = _keyring_user_credentials( use_keychain) if not password: if prompt == "osascript": # An "out-of-band" password prompt in order not to interrupt # the flow of `credential_process` to source the password password = prompt_password_using_osascript(config.adfs_user) elif prompt == "click": password = click.prompt('Password', type=str, hide_input=True) else: password = click.prompt('Password', type=str, hide_input=True) if use_keychain: keyring.set_password("aws-adfs", config.adfs_user, password) principal_roles, assertion, aws_session_duration = authenticator.authenticate( config, config.adfs_user, password) password = '******' del password if (role_arn is not None): config.role_arn = role_arn principal_arn, config.role_arn = role_chooser.choose_role_to_assume( config, principal_roles) if principal_arn is None or config.role_arn is None: click.echo('This account does not have access to any roles', err=True) exit(-1) # Use the assertion to get an AWS STS token using Assume Role with SAML # according to the documentation: # http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_assertions.html # This element contains one AttributeValue element that specifies the maximum time that the user # can access the AWS Management Console before having to request new temporary credentials. # The value is an integer representing the number of seconds, and can be # a maximum of 43200 seconds (12 hours). If this attribute is not present, # then the maximum session duration defaults to one hour # (the default value of the DurationSeconds parameter of the AssumeRoleWithSAML API). # To use this attribute, you must configure the SAML provider to provide single sign-on access # to the AWS Management Console through the console sign-in web endpoint at # https://signin.aws.amazon.com/saml. # Note that this attribute extends sessions only to the AWS Management Console. # It cannot extend the lifetime of other credentials. # However, if it is present in an AssumeRoleWithSAML API call, # it can be used to shorten the lifetime of the credentials returned by the call to less than # the default of 60 minutes. # # Note, too, that if a SessionNotOnOrAfter attribute is also defined, # then the lesser value of the two attributes, SessionDuration or SessionNotOnOrAfter, # establishes the maximum duration of the console session. _bind_aws_session_to_chosen_profile(config) conn = boto3.client( 'sts', config=client.Config(signature_version=botocore.UNSIGNED)) aws_session_token = conn.assume_role_with_saml( RoleArn=config.role_arn, PrincipalArn=principal_arn, SAMLAssertion=assertion, DurationSeconds=int(config.session_duration), ) if stdout: _store(config, aws_session_token) if role_chaining_role_arn: creds = aws_session_token['Credentials'] sts = boto3.client( "sts", aws_access_key_id=creds['AccessKeyId'], aws_secret_access_key=creds['SecretAccessKey'], aws_session_token=creds['SessionToken'], ) chained_token = sts.assume_role(RoleArn=role_chaining_role_arn, RoleSessionName=str(uuid4())) _emit_json(chained_token) else: _emit_json(aws_session_token) elif printenv: _emit_summary(config, aws_session_duration) _print_environment_variables(aws_session_token, config) else: _store(config, aws_session_token) _emit_summary(config, aws_session_duration)
def login( profile, region, ssl_verification, adfs_host, output_format, provider_id, s3_signature_version, ): """ Authenticates an user with active directory credentials """ config = prepare.get_prepared_config( profile, region, ssl_verification, adfs_host, output_format, provider_id, s3_signature_version, ) _verification_checks(config) # Try reauthenticating using an existing ADFS session principal_roles, assertion, aws_session_duration = authenticator.authenticate( config) # If we fail to get an assertion, prompt for credentials and try again if assertion is None: username, password = _get_user_credentials(config) principal_roles, assertion, aws_session_duration = authenticator.authenticate( config, username, password) username = '******' del username password = '******' del password principal_arn, config.role_arn = _chosen_role_to_assume( config, principal_roles) # Use the assertion to get an AWS STS token using Assume Role with SAML # according to the documentation: # http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_assertions.html # This element contains one AttributeValue element that specifies the maximum time that the user # can access the AWS Management Console before having to request new temporary credentials. # The value is an integer representing the number of seconds, and can be # a maximum of 43200 seconds (12 hours). If this attribute is not present, # then the maximum session duration defaults to one hour # (the default value of the DurationSeconds parameter of the AssumeRoleWithSAML API). # To use this attribute, you must configure the SAML provider to provide single sign-on access # to the AWS Management Console through the console sign-in web endpoint at # https://signin.aws.amazon.com/saml. # Note that this attribute extends sessions only to the AWS Management Console. # It cannot extend the lifetime of other credentials. # However, if it is present in an AssumeRoleWithSAML API call, # it can be used to shorten the lifetime of the credentials returned by the call to less than # the default of 60 minutes. # # Note, too, that if a SessionNotOnOrAfter attribute is also defined, # then the lesser value of the two attributes, SessionDuration or SessionNotOnOrAfter, # establishes the maximum duration of the console session. conn = boto3.client( 'sts', config=client.Config(signature_version=botocore.UNSIGNED)) aws_session_token = conn.assume_role_with_saml( RoleArn=config.role_arn, PrincipalArn=principal_arn, SAMLAssertion=assertion, DurationSeconds=3600, ) _store(config, aws_session_token) _emit_summary(config, aws_session_duration)
def test_set_and_get_client_config(self): client_config = client.Config() self.session.set_default_client_config(client_config) self.assertIs(self.session.get_default_client_config(), client_config)
def login( profile, region, ssl_verification, adfs_ca_bundle, adfs_host, output_format, provider_id, s3_signature_version, env, stdin, authfile, stdout, printenv, role_arn, session_duration, assertfile, sspi, print_console_url, run_console_url ): """ Authenticates an user with active directory credentials """ config = prepare.get_prepared_config( profile, region, ssl_verification, adfs_ca_bundle, adfs_host, output_format, provider_id, s3_signature_version, session_duration, sspi ) _verification_checks(config) # Try re-authenticating using an existing ADFS session principal_roles, assertion, aws_session_duration = authenticator.authenticate(config, assertfile=assertfile) # If we fail to get an assertion, prompt for credentials and try again if assertion is None: password = None if stdin: config.adfs_user, password = _stdin_user_credentials() elif env: config.adfs_user, password = _env_user_credentials() elif authfile: config.adfs_user, password = _file_user_credentials(config.profile, authfile) if not config.adfs_user: config.adfs_user = click.prompt(text='Username', type=str, default=config.adfs_user) if not password: password = click.prompt('Password', type=str, hide_input=True) principal_roles, assertion, aws_session_duration = authenticator.authenticate(config, config.adfs_user, password) password = '******' del password if(role_arn is not None): config.role_arn = role_arn # todo: break up AccountId and Role selection from the ARN strings. Prompt for Account then Role. # have a parameter for prompting for account/role like in yum prompts # make an option available for setting global default behaviors like SSPI, PROMPT, ect... principal_arn, config.role_arn = role_chooser.choose_role_to_assume(config, principal_roles) if principal_arn is None or config.role_arn is None: click.echo('This account does not have access to any roles', err=True) exit(-1) # Use the assertion to get an AWS STS token using Assume Role with SAML # according to the documentation: # http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_assertions.html # This element contains one AttributeValue element that specifies the maximum time that the user # can access the AWS Management Console before having to request new temporary credentials. # The value is an integer representing the number of seconds, and can be # a maximum of 43200 seconds (12 hours). If this attribute is not present, # then the maximum session duration defaults to one hour # (the default value of the DurationSeconds parameter of the AssumeRoleWithSAML API). # To use this attribute, you must configure the SAML provider to provide single sign-on access # to the AWS Management Console through the console sign-in web endpoint at # https://signin.aws.amazon.com/saml. # Note that this attribute extends sessions only to the AWS Management Console. # It cannot extend the lifetime of other credentials. # However, if it is present in an AssumeRoleWithSAML API call, # it can be used to shorten the lifetime of the credentials returned by the call to less than # the default of 60 minutes. # # Note, too, that if a SessionNotOnOrAfter attribute is also defined, # then the lesser value of the two attributes, SessionDuration or SessionNotOnOrAfter, # establishes the maximum duration of the console session. _bind_aws_session_to_chosen_profile(config) conn = boto3.client('sts', config=client.Config(signature_version=botocore.UNSIGNED)) aws_session_token = conn.assume_role_with_saml( RoleArn=config.role_arn, PrincipalArn=principal_arn, SAMLAssertion=assertion, DurationSeconds=int(config.session_duration), ) # todo: extract below secton of code to underscore function if run_console_url or print_console_url: # Format resulting temporary credentials into JSON url_credentials = {} url_credentials['sessionId'] = aws_session_token.get('Credentials').get('AccessKeyId') url_credentials['sessionKey'] = aws_session_token.get('Credentials').get('SecretAccessKey') url_credentials['sessionToken'] = aws_session_token.get('Credentials').get('SessionToken') json_string_with_temp_credentials = json.dumps(url_credentials) # 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 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) # 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. # # &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 # request_parameters = "?Action=login" request_parameters += "&Issuer=" + quote_plus_function(config.adfs_host) 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 # todo: fixed warning on WIN32 platform for ELSE below if no run param was set # Default browser opens URL if(sys.platform=="win32") and run_console_url: # todo: force logout - two URL exist for doing this in console interface #logout_url = 'https://signin.aws.amazon.com/oauth?Action=logout&redirect_uri=aws.amazon.com' logout_url = 'https://console.aws.amazon.com/console/logout!doLogout' # blocking logout before login required from subprocess import call call(['start', logout_url], shell=True) # execute the login to AWS console startfile(request_url) else: click.echo(u"""Warning: Cannot run AWS Console URL on non-windows platform.""") if stdout: _emit_json(aws_session_token) elif printenv: _emit_summary(config, aws_session_duration) _print_environment_variables(aws_session_token,config) if print_console_url: _print_console_url(request_url) else: _store(config, aws_session_token) _emit_summary(config, aws_session_duration) if print_console_url: _print_console_url(request_url)