AmazonS3ClientBuilder working with wrong credentials - java

Seeing as s3 client class got depreciated, I am trying to use this new static class provided to us by aws and it's confusing me quite a bit. I am creating a new client and passing it some false credentials, yet it does not throw any errors. Am I missing something here?
BasicAWSCredentials awsCreds = new BasicAWSCredentials("uselessinfo", "abcd1234");
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(awsCreds))
.withRegion(Regions.DEFAULT_REGION)
.build();
s3Client.getS3AccountOwner();
Also, even when I give correct credentials the getS3AccountOwner() method is unable to make a connection and keeps timing out.
What am I missing here?

Related

Getting preSignedUrl from s3 even if wrong access key or secret key is entered

I am generating a preSignedUrl and then uploading the file through that url.
The issue is that even if I enter the wrong access key or secret key I get the preSignedUrl, though if I try to upload using that url I get 400 error.
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>AuthorizationQueryParametersError</Code>
<Message>Query-string authentication version 4 requires the X-Amz-Algorithm, X-Amz-Credential, X-Amz-Signature, X-Amz-Date, X-Amz-SignedHeaders, and X-Amz-Expires parameters.</Message>
<RequestId>{requestId}</RequestId>
<HostId>{hostId}</HostId>
</Error>
Is there some way I get the error while generating the preSignedUrl so that I don't have to try and upload the file.
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("accessKey", "secretKey")))
.withRegion(clientRegion)
.build();
GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectKey)
.withMethod(HttpMethod.PUT)
.withExpiration(expiration);
URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
Generating a pre-signed URL doesn't require an API call; it can be generated by the framework using the specified access key and secret.
The generated URL will be validated by S3 when the request is received, and will obviously only be accepted when valid credentials were used for generating it.
Bottom line: in order to validate your credentials you need to make an API request that actually performs a call to AWS. This can be pretty much any other method on your s3Client.
Let's start with this:
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("accessKey", "secretKey")))
Static credentials go against AWS best practice. Instead, rely on credentials provided via environment variables or an execution role (when running on EC2, ECS, or Lambda).
The only way that you can verify that the credentials are valid is to try them. You could write a small dummy file, however this may cause problems for anything that is supposed to read that file, due to eventual consistency on S3.
There's also the problem that the expiration that you give the URL may not correspond to the lifetime of the credentials.
The best solution to all of these problems is to create a role that has access to PUT the files on S3, and has a duration consistent with your URL expiration (note that the maximum is 12 hours), then explicitly assume that role in order to construct the request:
final String assumedRoleArn = "arn:aws:iam::123456789012:role/Example";
final String sessionName = "example";
final String bucketName = "com-example-mybucket";
final String objectKey = "myfile.txt";
final int expirationSeconds = 12 * 3600;
final Date expiresAt = new Date(System.currentTimeMillis() + expirationSeconds * 1000);
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.defaultClient();
AWSCredentialsProvider credentialsProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(assumedRoleArn, sessionName)
.withStsClient(stsClient)
.withRoleSessionDurationSeconds(expirationSeconds)
.build();
AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withCredentials(credentialsProvider).build();
URL presignedUrl = s3Client.generatePresignedUrl(bucketName, objectKey, expiresAt, HttpMethod.PUT);

AWS Lambda with Java unable to GET a file from S3

I'm creating a very simple example with AWS Lambda and I have problem using Java runtime. I have to read a S3 object from a bucket of mine and with a NodeJS example like the following I have no problem
var S3FS = require('s3fs');
exports.handler = (req, res) => {
var s3Options = {
region: 'eu-west-3',
accessKeyId: 'key',
secretAccessKey: 'secret'
};
var fsImpl = new S3FS('mybucket', s3Options);
fsImpl.readFile("myfile",function (err,data) {
if (err) throw err;
console.log(data.toString());
});
}
If I try a similar Java example my function always timeouts (even if I increase to 1 minute)
context.getLogger().log("Before");
BasicAWSCredentials awsCreds = new BasicAWSCredentials("key", "secret");
AmazonS3 s3 = AmazonS3ClientBuilder.standard()
.withRegion("eu-west-3")
.withCredentials(new AWSStaticCredentialsProvider(awsCreds))
.build();
context.getLogger().log("client created");
S3Object object = s3.getObject(
new GetObjectRequest(bucketName, key));
context.getLogger().log("After");
The function always blocks when creating the S3 client. I know I can avoid using the key and secret in the Lambda, but also in this way the function blocks. It isn't a policy problem because I'm testing these examples from the same Lambda configuration so I think it's something related to the Java AWS S3 API. Any suggestions?
The Java lambda finally works using defaultClient() and not standard() method of AmazonS3ClientBuilder.
The difference between these two methods are the credentials, retrieved from env or passed as arguments. There is probably a wrong configuration I don't see, but anyway a more clear error could be useful

new AmazonS3Client(credentials); is not working in AWS lambda

I am using aws lambda in java to resize images on s3
following code doesn't work inside lambda and neither it initialize s3client nor throws any error.
AWSCredentials credentials = new BasicAWSCredentials("KEY", "PASSWORD");
AmazonS3 s3Client = new AmazonS3Client(credentials);
Can some one healp me out with this?

Setting AWS S3 Region

I am trying to create an aws s3 bucket using the following java code.
AmazonS3 s3client = AmazonS3ClientBuilder.defaultClient();
s3client.setRegion(Region.getRegion(Regions.AP_SOUTH_1));
But I am getting the following error:
"exception": "com.amazonaws.SdkClientException",
"message": "Unable to find a region via the region provider chain. Must provide an explicit region in the builder or setup environment to supply a region."
Am I trying to set region in an incorrect way? Please advice.
If you are not using any proxies and you already setup your credentials, you can use below code:
AmazonS3 s3client = AmazonS3ClientBuilder.standard()
.withRegion(Region.getRegion(Regions.AP_SOUTH_1));
But if you need to setup a proxy and manually set the credentials, you can use below code:
AWSCredentials cred = new BasicAWSCredentials(<accessKey>,<secretKey>);
AmazonS3 s3client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(cred))
.withClientConfiguration(<your configuration>)
.withRegion(Region.getRegion(Regions.AP_SOUTH_1));
The reason you are getting the error is you have not setup AWS with Eclipse.
If you are using Eclipse as your IDE then read:
http://docs.aws.amazon.com/toolkit-for-eclipse/v1/user-guide/welcome.html
Once the profile is setup then
AmazonS3 s3 = new AmazonS3Client(new ProfileCredentialsProvider());
Region apSouth1 = Region.getRegion(Regions.AP_SOUTH_1);
s3.setRegion(apSouth1);
Also make sure to import:
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;

AmazonS3Client is deprecated how to get s3client object with using credential

For getting s3 client object i am using below code.
BasicAWSCredentials creds = new BasicAWSCredentials(key, S3secretKey);
AmazonS3 s3Client =AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(creds)).build();
Getting below errors
Unable to find a region via the region provider chain. Must provide an explicit region in the builder or setup environment to supply a region.
I had to change to:
AmazonS3 client = AmazonS3ClientBuilder.standard()
.withRegion(Regions.US_EAST_1)
.withForceGlobalBucketAccess(true)
.build();
to emulate the "old" way (i.e. new AmazonS3Client() )
With a builder you need to provide your S3 bucket region using builder method, like .withRegion(Regions.US_EAST_1)
One way to do it with the 1.11.98 version of the sdk, in your code, you would do:
AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
And you need to have ~/.aws/credentials and ~/.aws/config files:
~/.aws/credentials contents:
[pca]
aws_access_key_id = KDDDJGIzzz3VVBXYA6Z
aws_secret_access_key = afafaoRDrJhzzzzg/Hhcccppeeddaf
[deault]
aws_access_key_id = AMVKNEIzzzNEBXYJ4m
aws_secret_access_key = bU4rUwwwhhzzzzcppeeddoRDrJhogA
~/.aws/config contents:
[default]
region = us-west-1
[pca]
region = us-west-1
Make sure they're readable, and that you export a profile if you have multiple as above before starting your service:
alper$ export AWS_PROFILE="pca"
There's a good description here

Categories

Resources