I am trying to create an application where a user can sign in and then have access to certain api resources based on their roles.
Users are moved into groups in the user pool and each group has a custom IAM role.
I have used to amplify CLI tools to create the authentication, api gateway and lambda function. This is the API set up in amplify
? Please select from one of the below mentioned services: REST
? Please select the REST API you would want to update standardApi
? What would you like to do Update path
? Please select the path you would want to edit /std
? Provide a path (e.g., /book/{isbn}): /std
? Choose a Lambda source Use a Lambda function already added in the current Ampl
ify project
? Choose the Lambda function to invoke by this path standardFunction
? Restrict API access Yes
? Restrict access by? Individual Groups
? Select groups: standard
? What kind of access do you want for standard users? create, read, update, dele
te
Successfully updated resource
The resources are created as expected when checked in the console.
The trouble is that when attempting to call the API, I am receiving a MissingAuthenticationTokenException
This is the call
const apiName = 'standardApi';
const path = '/std';
const myInit = {
headers: {},
response: false
};
API.get(apiName, path, myInit)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error.response);
});
My understanding is that the Amplify sdk should automatically populate the request headers with the correct authentication values.
If I attempt passing in the access token manually,
headers: {
Authorization: (await Auth.currentSession()).getIdToken().getJwtToken()
},
I get IncompleteSignatureException, with the message
Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header.
Trying
headers: {
Authorization: `Bearer ${(await Auth.currentSession()).getIdToken().getJwtToken()}
},
results in IncompleteSignatureException with no message.
Other posts have suggested that the endpoint may no be specified correctly, if I remove auth from the api in the console and redeploy, the endpoint is hit as expected. Futhermore, if I create a custom authorizer with the cognito user pool, the endpoint is hit correctly when signed in and a bearer token in passed.
It's just the IAM case that is not working.
Inspecting the ID token shows that the correct username, groups and roles are being passed in.
"cognito:groups": Array [ "standard" ]
"cognito:preferred_role": "arn:aws:iam::************:role/region-*_*********-standardGroupRole"
"cognito:roles": Array [ "arn:aws:iam::************:role/region-*_*********-standardGroupRole"]
"cognito:username": "0a******-****-****-****-************"
The Amplify configure step is being done with auto-generated aws-exports file, which contains correct entries for user pool, identity pool and client app.