aws cloudsearch uploadDocument returning signaturedoesnotmatch - amazon-cloudsearch

Im using com.amazonaws.services.cloudsearchdomain.AmazonCloudSearchDomainClient to uploadDocuments() with passing AWS secretkey and access id, End points .
Access Policy - Access all for all services
It is returning
Service: AmazonCloudSearchDomain; Status Code: 403; Error Code:
SignatureDoesNotMatch;
But with same package i have tried search() with same credentials , im getting search result correctly as expected.
Some one please help for above exception

This may be caused by your access policy allowing public access to search requests, but not upload. So there may be an issue with the credentials being passed, but you don't see that error when performing search requests, because credentials aren't necessary for that type of request.
For example, this access policy below would allow anyone to search without presenting credentials. But any other operation (like uploading documents) would require a valid set of credentials that have access to the CloudSearch domain.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "cloudsearch:search"
}
]
}

Related

Why AWS CloudWatch Alarm cannot send notification to encrypted SNS Topic?

I set up alerts to notify me if my lambda function memory usage is more than 80% of the lambda memory size. I'm capturing the data points using custom metrics and I am able to see the alerts in the cloudwatch console when the the memory usage is over the threshold. But when Alarm takes the action to send a notification to the corresponding SNS topic is failed with this message:
{
"actionState": "Failed",
"stateUpdateTimestamp": 1558142246126,
"notificationResource": "arn:aws:sns:us-east-1:5847563209:<myTopic>",
"publishedMessage": null,
"error": "null (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: 6b7806a6-2c16-4582-9ecd-05100161746e)"
}
The SNS topic is encrypted with KMS key and I allowed cloudwatch to access the key in the key policy:
{
"Sid": "Allow CloudWatch to use the key",
"Effect": "Allow",
"Principal": {
"Service": "cloudwatch.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "*"
}
But still the action is being failed. I've also tried events.amazonaws.com as the principal but no luck. I appreciate any help on this.
Looks like it's not yet supported. From here: https://aws.amazon.com/blogs/compute/encrypting-messages-published-to-amazon-sns-with-aws-kms/
As of November 2018, Amazon CloudWatch alarms don’t yet work with
Amazon SNS encrypted topics.

How do I access s3 bucket from IAM account using Java

I have an s3 account with AmazonS3FullAccess put when I try to use it to run s3.listObjects("name") I get a 403 error...
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>59C510407179770D</RequestId><HostId>aLPzqYkTKx6nkUWVtZWYS+2fYexzniKWkn2D9+aG6pdxBAjtxAcC85uvGC4HqDnQIifLaf+oy1E=</HostId></Error>
s3.doesBucketExistV2("name") returns true.
My policy looks like this...
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
Do I need to add the user somewhere?
Update
Looks like it could be a problem with not getting the AWS creds (which is weird becuase of this line)...
Deprecated. By doesBucketExistV2(String) which will correctly throw an exception when credentials are invalid instead of returning true. See Issue #1256.
If I run ((AmazonS3Client) s3).awsCredentialsProvider.getCredentials() it returns null. My creds are in a amazon.properties file like this...
#PropertySources({
#PropertySource("classpath:amazon.properties")
})
// amazon.properties
amazon.accessKey=${AMZN_ACCESS_KEY}
amazon.secretKey=${AMZN_SECRET_KEY}
aws.accessKeyId=${AMZN_ACCESS_KEY}
aws.secretKey=${AMZN_SECRET_KEY}
and echo $AMZN_ACCESS_KEY returns the value I would expect.
Update 2
It appears to be something with the properties not getting read properly if I am explicit like this...
BasicAWSCredentials awsCreds = new BasicAWSCredentials(key, secret);
final AmazonS3 s3 = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(awsCreds))
.withRegion(service.getRegion())
.build();
It worked, so 2 questions 1.) Why does the doesBucketExistV2 return true even when I am not logged in properly 2.) Why are the system properties not working?
You need to pass bucket name as below. The sample code should be as below
Refer here.
/* The following example list two objects in a bucket. */
var params = {
Bucket: "name",
MaxKeys: 2
};
s3.listObjects(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response

Terraform s3 event notification error

I am having trouble trying to create s3 event notifications. Does anyone know the resolutions to this?
Error is:
*Error applying plan:
1 error(s) occurred:
* module.Test-S3-Bucket.aws_s3_bucket_notification.s3-notification: 1 error(s) occurred:
* aws_s3_bucket_notification.s3-notification: Error putting S3 notification configuration: InvalidArgument: Unable to validate the following destination configurations
status code: 400, request id: AD9B5BF2FF84A6CB, host id: ShUVJ+TdkpqAZfpeDM3grkF9Vue3Q/AF0LydchperKTF6XdQyDM6BisZi/38pGAh/ZqS+gNyrSM=*
Below is the code that gives me the error:
resource "aws_s3_bucket" "s3-bucket" {
bucket = "${var.bucket_name}"
acl = ""
lifecycle_rule {
enabled = true
prefix = ""
expiration {
days = 45
}
}
tags {
CostC = "${var.tag}"
}
}
resource "aws_s3_bucket_notification" "s3-notification" {
bucket = "${var.bucket_name}"
topic {
topic_arn = "arn:aws:sns:us-east-1:1223445555:Test"
events = [ "s3:ObjectCreated:*", "s3:ObjectRemoved:*" ]
filter_prefix = "test1/"
}
}
If you haven't done it already, you need to specify a policy on the topic that grants the SNS:Publish permission to S3 (only from the bucket specified in the Condition attribute) - if you are also provisioning the topic via Terraform then something like this should do it (we know, as it caught us out just a few days ago too!):
resource "aws_sns_topic" "my-sns-topic" {
name = "Test"
policy = <<POLICY
{
"Version":"2012-10-17",
"Statement":[{
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:us-east-1:1223445555:Test",
"Condition":{
"ArnLike":{"aws:SourceArn":"${aws_s3_bucket.s3-bucket.arn}"}
}
}]
}
POLICY
}
Hope that helps.
Well, I know that this is not your exact case, but I had the same error and I didn't manage to find an answer here, and because this post is the first that Google gave me, I will leave the answer to my case here in the hope that it will help someone else.
So, I notice that after Terraform apply I had this error and I went to the UI to see what happened and found this message:
The Lambda console can't validate one or more event sources for this trigger. The most common cause is when a source ARN includes a wildcard (*) character. You can manage unvalidated triggers using the AWS CLI or AWS SDK.
And guess what? I really had a wildcard (*) character in ARN like this:
source_arn = "{aws_s3_bucket.bucket.arn}/*"
So I changed it to:
source_arn = aws_s3_bucket.bucket.arn
And it worked. So, if you read this - there might be the same mistake in your case.

What causes "Incorrect token audience" using Google authentication tokens with AWS

I'm creating a simple web application that will use Google authentication to return an OpenID token, and then pass that token to AWS using javascript WebIdentityCredentials.
What I have done:
Created the Google Project, and saved the OAuth ClientID
Created an IAM role using Google IDP, and OAuth ClientID as Audience field.
Include both Google API and AWS API javascript in web page configured with above.
(Client) Request the id token from Google using the google js api
Configure the id token on an WebIdentityCredentials
Retrieve the AWS credentials (using that token)
When retrieving the credentials, I get this error from STS:
<ErrorResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
<Error>
<Type>Sender</Type>
<Code>InvalidIdentityToken</Code>
<Message>Incorrect token audience</Message>
</Error>
<RequestId>28d09368-bf98-11e5-b52f-953b4c773ebf</RequestId>
</ErrorResponse>
Here is the AWS role:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Federated": "accounts.google.com"},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"accounts.google.com:aud": "<my-oauth-client-id>"
}
}
}
]
}
And here is the code I use to configure the token on the AWS context:
AWS.config.update({
region: 'us-east-1',
credentials: new AWS.WebIdentityCredentials({
RoleArn: 'arn:aws:iam::<my-acct>:role/lab-amp-google-idp',
WebIdentityToken : token
})
});
And here is where I test the credentials by fetching them:
AWS.config.credentials.get(function(err) {
if (err) console.log(err);
else console.log(AWS.config.credentials);
});
I have validated the id token using jwt.io and I can see it has the proper expected fields. The "aud" and "azp" properties have the OAuth Client ID. I also double checked the Trust stansza in the AWS role to confirm it also has the exact same OAuth Client ID in the Condition.
I have passed in other invalid tokens and altered the RoleArn just to see the different errors, which I do.
I cannot find anything on the web describing reasons for "Incorrect token audience" so I'm at a loss for what to try next.

Amazon S3 Access image by url

I have uploaded an image to Amazon S3 storage. But how can I access this image by url? I have made the folder and file public but still get AccessDenied error if try to access it by url https://s3.amazonaws.com/bucket/path/image.png
This is an older question, but for anybody who comes across this question, once I made the file public I was able to access my image as https://mybucket.s3.amazonaws.com/myfolder/afile.jpg
in my case i have uploaded image privately so that i was unable to access. i did following code
const AWS = require('aws-sdk')
const myBucket = 'BUCKET_NAME'
const myKey = 'FILE_NAME.JPG'
const signedUrlExpireSeconds = 60 * 1
const s3 = new AWS.S3({
accessKeyId: "ACCESS_KEY_ID",
signatureVersion: 'v4',
region: 'S3_REGION',
secretAccessKey: "ACCESS_SECRET"
});
const url = s3.getSignedUrl('getObject', {
Bucket: myBucket,
Key: myKey,
Expires: signedUrlExpireSeconds
})
console.log(url)
You can access your image by using:
https://s3.amazonaws.com/bucketname/foldername/imagename.jpg
or if there are no folders, you can do:
https://s3.amazonaws.com/bucketname/imagename.jpg
upvote if helps. It conforms to present AWS dated 30 may 2017.
Seems like you can now simply right-click on any folder inside a bucket and select 'Make Public' to make everything in that folder public. It may not work at the bucket level itself.
One of easiest way is to make a bucket policy.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "MakeItPublic",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::yourbucketname.com/*"
}]
}
make sure you access image using the same case as it was uploaded and stored on S3.
for example, if you uploaded image_name.JPG, you should use the same name, but not image_name.jpg
For future reference, if you want to access a file in Amazon S3 the URL needs to be something like:
bucketname.s3.region.amazonaws.com/foldername/image.png
Example: my-awesome-bucket.s3.eu-central-1.amazonaws.com/media/img/dog.png
Don't forget to set the object to public.
Inside S3 if you click on the object will you see a field called: Object URL. That's the object's web address.
On your console, right click on the image you want to access and click on "Make Public"; when thats done right click on the image again and click on "Properties" and copy the Link from the Extended view.
I came across this question whilst looking for a solution to a similar problem with being unable to access images.
It turns out that images with a % in their filename, when being accessed, must have the % symbol URL encoded to %25.
i.e. photo%20of%20a%20banana%20-%2019%20june%202016.jpg needs to be accessed via photo%2520of%2520a%2520banana%2520-%252019%2520june%25202016.jpg.
However, URL encoding the full path didn't work for us, since the slashes, etc would be encoded, and the path would not work. In our specific case, simply replacing % with %25 in all access paths made the difference.
I was having the same problem. I have the issue the spacing in image url. I did this to make it work:
String imgUrl=prizes.get(position).getImagePreview().replaceAll("\\s","%20");
now pass this url to picasso:
Picasso.with(mContext)
.load(imgUrl)
.into(mImageView);
Just add Permission to follow the below image.
To access private images via URL you must provide Query-string authentication. 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.
Just addon to #akotian answer, you can get the object URL by clicking the object as follows
and to access publically you can set the ACL programmatically while uploading the object to the bucket
i.e sample java request
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.contentType(contentType)
.bucket(LOGO_BUCKET_NAME)
.key(LOGO_FOLDER_PREFIX+fileName)
.acl(ObjectCannedACL.PUBLIC_READ)// this make public read
.metadata(metadata)
.build();
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
]
}
]
}
use this policy for that bucket, which makes it public.
Adding bucket policy worked for me
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::yourbucketname/*"
}
]
}
Turn off Block public access (bucket settings) from Permissions tab inside your bucket. You also need to Edit the permissions of the object. Provide Read access on Grantee Everyone (public access). Then chech "I understand the effects of these changes on this object." and Save changes.
Change your Bucket.. It may works