2

I am trying to make a callout to AWS S3 using named credentials and Apex

The named credential is set up as follows

Label: AWS S3
Name: AWS_S3
URL: https://bucket-name.s3.amazonaws.com
-
Certificate:
Identity Type: Named Principal
Authentication Protocol: AWS Signature Version 4
AWS Access Key: AKIAxxxxxx
AWS Secret Access Key: xxxxxx
AWS Region: ap-southeast-2
AWS Service: s3
-
Generate Authorization header: true
Merge fields in header: false
Merge fields in body: false

The Apex class is very simple

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:AWS_S3');
req.setMethod('GET');                       
Http http = new Http();
HTTPResponse res = http.send(req);                
System.debug(res.getBody());
return res.getBody();

The response body contains the following:

SignatureDoesNotMatchThe request signature we calculated does not match the signature you provided. Check your key and signing method.AKIAxxxxx

I have used the same bucket, endpoint and credentials using Postman and am able to successfully return the list of objects in the bucket so it is not an IAM permissions issue

There have been a couple of similar questions on stackexchange but unfortunately they do not provide any resolution or assistance in this case: AWS Signature Version 4 Using Named Credentials AWS Signature Version 4 Named Credential doesn't seems like working

I've tried looking for code samples or further pointers in the Apex documentation but it doesn't really give any further guidance on how to proceed or correctly set this up so I'm a bit stuck

  • this AWS feature came out in Summer 19 (V46). Is your Apex class at V46? – cropredy Sep 24 at 1:18
  • Yes <?xml version="1.0" encoding="UTF-8"?> <ApexClass xmlns="urn:metadata.tooling.soap.sforce.com" fqn="s3Connector"> <apiVersion>46.0</apiVersion> <status>Active</status> </ApexClass> – Devst Sep 24 at 1:35
  • Interestingly enough a PUT operation to create a file with the same credentials works just fine! – Devst Sep 24 at 2:34
3

Okay so the answer is actually pretty straightforward so am leaving it here for anybody else struggling with the same issue.

The endpoint needs to have a trailing / so either your URL in the named credential needs to look like this https://bucket-name.s3.amazonaws.com/ Or when you are making the callout append the / in the Apex like this req.setEndpoint('callout:AWS_S3/');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.