2
votes

In AWS, I have built an API gateway which invokes a Lambda function. Users gain access by logging in to a Cognito User Pool associated with a Cognito Federated Identity Pool and the associated IAM roles contain API invoke permissions. The API Gateway method is a POST request.

If I use the User Pool as the authorizer of the API Gateway I am able to successfully trigger the Lambda function via an ajax request in my javascript web app - note though, this grants the same access to every user in the pool. I am trying to create different Cognito User Group based access for different methods and because I apparently cannot specify a different User Group for each method when using the Cognito User Pool as the authorizer, I am now seeing if I can secure the API using AWS_IAM as the API authorizer. However, if I select AWS_IAM as the authorizer I get back:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.

What might be the problem? How do I set up CORS correctly for this scenario and what should my ajax request look like in the client javascript? Does cognito take care of signing for me or do I need to do something to headers?

When I used the Cognito User Pool I had:

$.ajax({
    method: 'POST',
    url: _config.api.invokeUrl + '/savesurv', 
    headers: {
        Authorization: authToken
    },
    data: JSON.stringify(Data),
    contentType: 'application/json',
    success: callback,//console.log("complete"),
    error: function ajaxError(jqXHR, textStatus, errorThrown) {
        console.error('Error requesting save: ', textStatus, ', Details: ', errorThrown);
        console.error('Response: ', jqXHR.responseText);
        alert('An error occured when requesting to save:\n' + jqXHR.responseText);
    }
});

This worked in that case, do I need to change it when using AWS_IAM as authorization for the API Gateway?

1

1 Answers

3
votes

The problem here is that when you changed to use AWS_IAM as the authorizer for your API Gateway method the request must now contain specific amazon headers and not just Authorization header as you have specified.

This is called a signed Sigv4 request and more information on how to create the request can be found here:

https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html

So to answer your question, Cognito will not take care of the signing and you do have to do additional steps, or get a framework to handle that for you.

The way I got this to work was to use Amplify (https://aws-amplify.github.io/) to generate my API requests and this framework will take care of signing the requests for you.

I appreciate that is quite a high level answer but to go into Amplify here would be a bit off topic for your question.

It's worth noting that if you decode your JWT ID Token (the one that you are passing as authToken) using a tool such as https://jwt.io/ it contain details of the groups which your user is in which may give you something to work with. I'm assuming that API Gateway will validate the authenticity of the token so you can rely on the values it contains. Then in API Gateway you can get access to this detail.