AWS / Quicksight / AWS4Signer / Signature Mismatch - amazon-web-services

Iam trying to access datasets on quicksight using AWS4Signer, and i get the below response.
"message": "The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."
I ensured, all the input parameters(region,servicename, etc..) Iam providing are correct.
Same SecretAccessKey is working correctly, when used with S3.
my DefaultRequest field that i supply to aws4Signer.sign() looks as below.
GET https://quicksight.us-east-1.amazonaws.com/accounts/19XXXXXXXX20/data-sets?max-results=10 / Parameters: ({"max-results":["10"]}Headers: (x-amz-content-sha256: required, )
Same thing works when i issue a CLI command as below.
aws quicksight list-data-sets --aws-account-id 19XXXXXXXX20
Please let me know what could be missing here.
are there any quicksight specific headers that should be provided?

Related

Cant add message to AWS SQS using Postman - AcessDenied?

I am trying to add a message to my SQS using Postman.
When I try the following on Postman:
GET https://sqs.us-east-1.amazonaws.com/205115639995/myQueue.fifo?Action=SendMessage&MessageBody={"message":"test1}
I get:
<?xml version="1.0"?>
<ErrorResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
<Error>
<Type>Sender</Type>
<Code>AccessDenied</Code>
<Message>Access to the resource https://sqs.us-east-1.amazonaws.com/205115639995/myQueue.fifo is denied.</Message>
<Detail/>
</Error>
<RequestId>80ddb4e8-5eff-5143-adf6-e39d5cb46aa2</RequestId>
</ErrorResponse>
I have my AWS ACCESS and SECRET keys saved in my environment variables and they are correct.
What could be the issue here? Do I need to add my KEYS to the request?
The AWS credentials are picked up by AWS provided tools like AWS CLI, Boto3 (python) etc. They look at various places like environment variables, the credentials files that are generated by aws configure etc
Postman is not a AWS property, so this lookup logic is not built in. This is the reason why you are facing the issue.
There's a little bit of configuration that is needed to let Postman know that you want to use AWS credentials for a particular API calls.
Head over to the "Auth" tab when editing the Request.
From the "Type" dropdown, select "AWS Signature"
Here you will find a place to add your accesskey and secretkey as well as other optional parameters like region.
All set, if the service you are trying to connect to is publicly accessible, and the credentials you are using has a policy in place to access the service, you should now be authenticated to access it.
Image for your reference:

An error occurred (UnrecognizedClientException) when calling the ListTopicRules operation: The security token included in the request is invalid

I got this error when using aws CLI, following the tutorial shows below to configuring the AWS CLI, I can only set up the AWS Access Key ID and AWS Secret Access Key. Where can I set the security token?
https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html
I found the answer to this. It might seem very simple though.
Basically you were following the tutorial literally, which means you most probably input the exact AWS Access Key ID and AWS Secret Access Key mentioned in the tutorial.
However, those keys in red are just examples. What you should use are the keys from your own AWS account, i.e. My Security Credentials.

API Gateway export API definition with Postman

I was checking out a couple methods from amazon-api-gateway-developer-guide and I stumbled with api-gateway-export-api, I managed to get the AWSCLI command (aws apigateway get-export --parameters extensions='apigateway' --rest-api-id abcdefg123 --stage-name dev --export-type swagger latestswagger2.json --profile profile --region us-east-1) working by adding the --profile and --region parameters, but for whatever reason I can't get the Request URL to return the API definition response.
I am trying to do the following couple things (Postman):
GET request with the URL: https://apigateway.us-east-1.amazonaws.com/restapis/abcdefg123/stages/dev/exports/oas30
Add authorization type AWS-Signature to the request with all the
parameters filled (AccessKey, SecretKey, AWS Region,
Service Name and Session Token)
The Authorization, x-Amz-Date and x-Amz-Security token are generated successfully, as far as I can tell
I am also sending a the headers Host (apigateway.us-east-1.amazonaws.com) and Accept (application/yaml)
This results in the following error:
{"logref":"2734hu2r2873","message":"User:
arn:aws:sts::7216832187:assumed-role/DEVELOPER/xxxx is not authorized to perform:
apigateway:GET on resource:
arn:aws:apigateway:us-east-1::/restapis/abcdefg123 /stages/dev/exports/oas30"}
I was actually getting the same error with the AWSCLI command before I added the --profile and --region parameters. I already checked out a couple posts about issues like mine, this one is an example export swagger api definition from api gateway via http request?, but I am doing basically the same thing (sending the same headers, same host and URL) and getting this error. I don't think my access key, secret key, token or any of that information might be wrong... because it's the credentials I use for the AWSCLI command.
Thank you for the taking the time to read and/or reply to my post, I really appreciate any feedback in anything.
The point of trying to get this request to work is that I wanted to add it as an HTTP proxy to an API, unfortunately I couldn't get it to work.
My problem was that I have a couple profiles in my session and each one of them has different permissions, I found no way to specify the profile I wanted to use in the request and thus it caused the error mentioned above.
In the end I opted to write a Lambda function with proxy integration and everything went fine, after giving the lambda profile the apigateway:GET permission.
If I have a misconception about anything I wrote about or I am using a term in an incorrect way please correct me, I am still fairly new to AWS and have a lot to learn!

HTTP POST to AWS IoT

I want to connect a HTTP device to IoT core.
I have tried this with the curl command all goes well.
Now I want to try to use POST with signatyure version 4
I'm using postmand to send a POST request, but I got this output:
"message": "The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.",
In authorization fields I have chosen "AWS Signature" and I have completed all of them: access and secret key, aws region and service name=iotdata
I want to get the same results as when I use the curl command:
curl --tlsv1.2 --cacert YY.pem --cert XX.pem.crt --key ZZ.pem.key -X POST -d "{ \"Trama\": \"message\"}" "https://PPPPPP.iot.eu-west-1.amazonaws.com:8443/topics/topicname?qos=1"
The problem here is that both of your commands are a little different, because of the various ways you can send data to AWS IoT.
In the curl command you're actually using x.509 certificate approach (you can see here for further information: https://docs.aws.amazon.com/iot/latest/developerguide/managing-device-certs.html) This doesn't need the payload to be signed, it's already trusted because the certificate is.
This approach is mostly unique to AWS IoT, because the aim is that the data comes from lots of devices- and you wouldn't want to give them all an IAM Role. In fact, certificate is the recommended way to send data from a device.
You can use these certificates with Postman if you want, by adding them to the request under certificates tab (you only need the .crt and .key files). See https://www.getpostman.com/docs/v6/postman/sending_api_requests/certificates for more detailed instructions.
You still can use AWS v4 signatures (https://docs.aws.amazon.com/iot/latest/developerguide/iam-users-groups-roles.html) so the suggestion is that you're not forming the request properly.
Looking at this documentation (https://docs.aws.amazon.com/iot/latest/apireference/API_iotdata_Publish.html) you should be using:
Method: POST
Uri: <AWS IoT Endpoint>/<url_encoded_topic_name>?qos=1 (e.g. https://a1pn10j0v8htvw.iot.us-east-1.amazonaws.com:8443/topics/iotbutton/virtualButton?qos=1)
Authorisation Type: AWS Signature
AccessKey / SecretKey: As per your credentials
AWS Region: Region you AWS IoT instances is in
Service Name: iotdata
Session Token: Leave blank

How to access pre-signed urls for AWS Cloudwatch Logs generated with boto3.client?

I am wondering if it is possible to use pre-signed urls with other aws services other than s3. Specifically, the boto3 documentation http://boto3.readthedocs.io/en/latest/reference/services/logs.html#CloudWatchLogs.Client.generate_presigned_url shows that the method generate_presigned_url is available for cloudwatch logs. I've tried using it in the following fashion.
client = boto3.client(
'logs',
aws_access_key_id="<aws_access_key_id>",
aws_secret_access_key="<aws_secret_access_key>",
region_name='us-east-1'
)
url = client.generate_presigned_url(
ClientMethod='get_log_events',
Params={
'logGroupName':'<logGroupName>',
'logStreamName':'<logStreamName>'
},
ExpiresIn=180
)
The url generates, but when trying to access the url I get the error in the browser:
<InvalidSignatureException>
<Message>The request signature we calculated does not match the
signature you provided. Check your AWS Secret Access Key and signing
method. Consult the service documentation for details.</Message>
</InvalidSignatureException>
For reference, the url is in this format (AWS Signature Version 4):
https://logs.us-east-1.amazonaws.com/
?logGroupName=<logGroupName>&logStreamName=<logStreamName>
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=<aws_access_key_id>%2F20130721%2Fus-east-
1%2Fs3%2Faws4_request
&X-Amz-Date=20180531T150510Z
&X-Amz-Expires=180
&X-Amz-SignedHeaders=content-type%3Bhost%3Bx-amz-target
&X-Amz-Signature=<signature-value>
How can I access this url? I noticed this url has a different format than the ones generated for s3, which works with the same method (i.e. generate_presigned_url with get_objects). Is there a way to make this work with Cloudwatch Logs?