AWS Java SDK: How to Build AWSClient That Uses the Auth Profile with aws_security_token
I am trying to use the AWS Java SDK to interact with S3 and Lambda.
Since our accounts must use multi-factor authentication, the ~ / .aws / credentials file has two profiles: [default] and [auth]. The default is aws_access_key_id
and aws_secret_access_key
, generated through the IAM Management Console, but this profile cannot be used for most actions. The second profile auth
is created by a script that uses the MFA code to create a set of credentials that will last 12 hours. It has aws_security_token
in addition to aws_access_key_id
and aws_secret_access_key
. (Potentially, this aws_security_token is NOT in my IAM management console, but the profile works fine with the AWS CLI, and my colleagues confirm that the same is true for them.)
I've tried various permutations of creating an S3 or Lambda client:
//private static AWSLambdaClient lambda = new AWSLambdaClient();
private static AWSLambda lambda = AWSLambdaClientBuilder.standard().withCredentials(new ProfileCredentialsProvider("auth")).withRegion(Regions.US_WEST_2).build();
//private static AmazonS3 s3client = new AmazonS3Client();
private static AmazonS3 s3client = new AmazonS3Client(new ProfileCredentialsProvider("auth"));
In all cases, this fails when I try to do anything with these clients. (Either s3client.listBuckets()
, or lambda.invoke(request)
.)
With the default profile, it doesn't work in the expected ways - saying that the user doesn't have permission to do this.
With the "auth" profile, it does not work differently for S3 and Lambda. S3 Not Working: "The AWS Access Key ID you provided does not exist in our records." Lambda fails with "Invalid security token included in request.
Complete error message below:
S3 with default profile:
Exception in thread "main" com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 1A8FE9A40C6CF4FC), S3 Extended Request ID: M+IaUw223nj7ClIv3oB4sp7pOw2af8VMsrhLl/18oQB0rLMRFNjf8LFyXKj+AQNanGoUVgMpPNM=
S3 with auth profile:
Exception in thread "main" com.amazonaws.services.s3.model.AmazonS3Exception: The AWS Access Key Id you provided does not exist in our records. (Service: Amazon S3; Status Code: 403; Error Code: InvalidAccessKeyId; Request ID: E388FFE85FC71492), S3 Extended Request ID: f3RU7uEXK+2tt98fQYCkHMbsa7odsnsgTIdRJvx2xbvKUmDtT2xXWZ2Eqor1I1ODqEZ0xDe3Quc=
Lambda with default profile:
Caused by: com.amazonaws.services.lambda.model.AWSLambdaException: User: arn:aws:iam::181136347741:user/bkc is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-1:181136347741:function:sensor (Service: AWSLambda; Status Code: 403; Error Code: AccessDeniedException; Request ID: e4670c43-61b6-11e7-8eeb-db8360af9fe6)
Lambda with auth profile:
Caused by: com.amazonaws.services.lambda.model.AWSLambdaException: The security token included in the request is invalid. (Service: AWSLambda; Status Code: 403; Error Code: UnrecognizedClientException; Request ID: 00a397f0-61b7-11e7-beb6-df232368bb9e)
So what am I doing wrong here? Is there something wrong with how I create ProfileCredentialsProvider
and distribute it to AWS clients? Is there something wrong with my profile auth
even though it works from the CLI? (Is there anything we need to fix in our script that possibly creates an auth profile?)
For reference, here's the interesting parts of the script that generate the auth profile:
def get_mfa_tokens(serial, code):
'''Generate MFA access tokens using the given device serial and MFA code.'''
sts = boto3.client('sts')
return sts.get_session_token(
SerialNumber=serial,
TokenCode=code)
def add_auth_tokens(config, tokens):
'''Modify the given config object, adding certain token fields to it.'''
#auth section will be there most of the time, so LBYL.
if not config.has_section('auth'):
config.add_section('auth')
config.set('auth', '# expires {}'.format(tokens['Credentials']['Expiration']))
config.set('auth', 'aws_access_key_id', tokens['Credentials']['AccessKeyId'])
config.set('auth', 'aws_secret_access_key', tokens['Credentials']['SecretAccessKey'])
config.set('auth', 'aws_security_token', tokens['Credentials']['SessionToken'])
source to share
No one has answered this question yet
Check out similar questions: