Trouble with AWS Cognito, API Gateway, Amplify. Requests are always anonymous and return a 403

99 views Asked by At

I'm trying to make authenticated requests to API Gateway where I've set a Resource Policy which restricts access to some resources to a IAM role.

No matter the settings I try, all requests to a resource protected by the IAM role return a 403 with the message "User: anonymous is not authorized to perform: execute-api:Invoke on resource "

Looking at cloudwatch logs I see that context.identity and context.authorizer.principalId are always '-'

I'm using aws-amplify/ui-react to configure the front end app and added my user pool, identity pool and API resulting in a config like this:

(truncated a bit)

const awsmobile = {
    "aws_project_region": "us-east-1",
    "aws_cognito_identity_pool_id": "us-east-1:bla-blabla-bla-blabla",
    "aws_cognito_region": "us-east-1",
    "aws_user_pools_id": "us-east-1_XXXXXXXXX",
    "aws_user_pools_web_client_id": "foostuffboostuff",
    "oauth": {
        "domain": "jefarr-test.auth.us-east-1.amazoncognito.com"
    },
    "aws_cloud_logic_custom": [
         {
             "name": "Cognito Test API",
             "endpoint": "https://foobar.execute-api.us-east-1.amazonaws.com/Test",
             "region": "us-east-1"
         }
     ]
 
};

and my React app looks like this:

import React, { useEffect } from 'react';
import { Amplify, Auth, API } from 'aws-amplify';
import { withAuthenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';

import awsmobile from './aws-exports.js';
Amplify.configure(awsmobile)

function App({ signOut, user }) {

    async function callApi() {
      const user = await Auth.currentAuthenticatedUser()
      const token = "Bearer: " + user.signInUserSession.idToken.jwtToken
      const apiName = 'Cognito Test API';
      const path = '/';
  
      const requestData = {
          // headers: { // tried this from the docs, it didn't work.
          //   Authorization: token
          // }
      }
      const data = await API.get(apiName, path, requestData)
      console.log("data: ", data)
    }
        
    return (
    <>
      <h1>Hello {user.username}</h1>
      <button onClick={signOut}>Sign out</button>
      <button onClick={callApi}>Call Api</button>
    </>
  
  );
}
export default withAuthenticator(App);

lastly, here's the relevant Resource Policy on the Gateway:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::840866145964:role/service-role/jefarr-cognito-test-identity-pool-role"
      },
      "Action": "execute-api:Invoke",
      "Resource": "arn:aws:execute-api:us-east-1:840866145964:pu0xzl6eb9/*/*/*"
    }
  ]
}

I've configured a User Pool and an App Client. I've configured a Identity Pool with a role for authenticated and guest access (matches the above policy), and configured an Identity Provider associated with the app client ID from my user pool.

Looking at the dev tools, I see requests to:

AWSCognitoIdentityProviderService.GetUser
AWSCognitoIdentityService.GetCredentialsForIdentity
AWSCognitoIdentityService.GetId

But when I look at the idToken and accessToken via javascript console I don't see an entry for cognito:roles or any indication that the Identity Pool info is included.

0

There are 0 answers