Search code examples
restkitaws-lambdaamazon-cognitoamazon-iam

AWS API Gateway + Cognito User Pool Authorizer + Lambda - Which HTTP-headers and permissions do I need to set?


I have problems getting the authorization of my API on AWS for a Cognito User Pool via HTTP headers (without AWS API Gateway SDK) to work.

My setup:

On AWS:

  • A REST API implemented on AWS Lambda (deployed via Serverless framework),
  • exposed via API Gateway using type LAMBDA_PROXY (no manual mapping)
  • Authorization on API Gateway via the provided "Cognito User Pool authorizer" (no "AWS_IAM" option, no custom coded authorizer)
  • Testing the API via Postman

On the iOS client

  • Registration/Sign-In via AWS Cognito (SDK and UI copied from the AWS Mobile Hub generated demo Xcode project)
  • Accessing the REST API via RestKit, not using the AWSAPIGateway SDK

What is working:

The API methods get properly deployed via serverless.

I can call the public (not set to use the user pool) via Postman.

For the private API methods, I can see the Cognito user pool authorizer set up in the API Gateway management console, including "Identity token source" set to method.request.header.Authorization (the default) as described here

On iOS, I can properly register and log in as user. I can dump the AWS Credentials details to the console, showing AccessKey, SecretKey and SessionKey.

On iOS, I can query the public API via RestKit.

When I try to call a private API method via Postman, I get back an HTTP error 401 with the body {"message": "Unauthorized"}. (Which is expected, without setting any authorization.)

What fails:

To test the authorization, in Postman, I have tried

The result was always the same 401 error.

What do I need to set as HTTP headers, in order to authorize the calls to the private API? "Authorization" should work - maybe I am missing some role permissions?

How can I better debug the permissions / authorization flow?


Solution

  • This is how to get the session:

    AWSCognitoIdentityUserPool *pool = [AWSCognitoIdentityUserPool CognitoIdentityUserPoolForKey:AWSCognitoUserPoolsSignInProvi‌​derKey]; 
    AWSCognitoIdentityUser *user = [pool currentUser]; 
    AWSTask<AWSCognitoIdentityUserSession *> *task = [user getSession];
    

    Then, task.result.idToken.tokenString can be set as "Authorization" header, and it works.

    Thanks Peter for the tip!