17

For a Kinesis stream, I created a proxy API using AWS API Gateway. I added a custom authorizer using python Lambda for the proxy. After publish of lambda function and deploy of API, I was able to successfully test the API using Gateway Test functionality. I could see the logs in cloudwatch which had detailed prints from custom auth lambda function. After successful authentication, API Gateway pushed the record to my Kinesis stream

However when I call the same API from Chrome Postman client, I get 500 Internal Server Error and response headers includes X-Cache → Error from cloudfront, x-amzn-ErrorType → AuthorizerConfigurationException

Lambda auth function returns the policy which allows execute request for my API. Policy Document returned is:

            {
              "policyDocument": {
                "Version": "2012-10-17",
                "Statement": [
                  {
                    "Action": "execute-api:Invoke",
                    "Resource": [
                      "arn:aws:execute-api:us-east-1:1234567:myapiId/staging/POST/*"
                    ],
                    "Effect": "Allow"
                  }
                ]
              },
              "principalId": "Foo"
            }

Why does the request fail from Chrome or curl but the same API test works fine from API Gateway?

suman j
  • 6,710
  • 11
  • 58
  • 109
  • It essentially means that your authorizer did not return a policy or returned invalid policy or returned a policy unauthorizing the API request. authorizer code would have failed for some reason in case a policy has not been returned... – Prabhat Nov 22 '16 at 11:53

5 Answers5

14

AuthorizerConfigurationException is usually an indication that API Gateway failed to call your authorizer due a permissions error.

Please either make sure you've properly configured your function to be invoked by API Gateway. An easy to reset this is by removing and re-adding the function to your authorizer. The console will then prompt you to add the necessary permissions.

Bob Kinney
  • 8,870
  • 1
  • 27
  • 35
  • Hey Bob, can you expand a little more on how I would "configure my function to be invoked by API gateway", please? – Stretch Oct 06 '16 at 22:10
  • @Stretch You have to allow API Gateway to invoke your function. See [this question](http://stackoverflow.com/questions/38027414/giving-aws-api-gateway-permission-to-invoke-lambda-function-using-boto3) for an example using the AWS CLI. – Bob Kinney Oct 07 '16 at 16:08
  • [This documentation page goes deeper in the details](http://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-lambda.html). Briefly, your api-gw needs to have Lambda/Invoke permissions. If you are defining your custom authorizer via swagger, ensure the role in authorizerCredentials has lambda/invoke and is assumable by api-gw (in the trusted entities). – deddu Jun 29 '17 at 10:28
  • 9
    Not true. `AuthorizerConfigurationException` is for all Exceptions thrown during Authorizer execution, unless they're mapped using Gateway Response Mapping. – Kashyap Jun 04 '18 at 17:22
  • I had to remove the resource from the API Gateway, then add it back, which correctly added the permissions. – esengineer Sep 20 '22 at 17:14
8

I was facing the same error, in my case a nodejs function, I was adding one context key as array.

{
  policyDocument: {
  Version: '2012-10-17',
  Statement: [{
    Action: 'execute-api:Invoke',
    Effect: effect,
    Resource: `${arn.split('/').slice(0, 2).join('/')}/*`,
  }],
},
context: {
  roles: ['admin']
}

As doc says:

You can access the stringKey, numberKey, or booleanKey value (for example, "value", "1", or "true") of the context map in a mapping template by calling $context.authorizer.stringKey, $context.authorizer.numberKey, or $context.authorizer.booleanKey, respectively. The returned values are all stringified. Notice that you cannot set a JSON object or array as a valid value of any key in the context map.

Remove the role key and it's working.

Natan Deitch
  • 556
  • 8
  • 12
  • 2
    aside from returning a json object, https://stackoverflow.com/a/38640522/5031727, and the issues Natan raised above, make sure the keys in the returned object are camelCased. but the error refers to a wide range of issues as others mentioned. good logging will be very helpful. – valearner Jul 29 '20 at 17:34
  • and if you want to get roles in context, just use for eg. a context.authorizer = JSON.stringify({roles}); – AgBorkowski Nov 22 '22 at 08:36
6

Figured out what was causing the issue. From python lambda function, I was returning a json string instance. Instead it should be json object. Its strange that the same lambda function did not error when I tested the API from API Gateway "test" feature. But when the API was called from internet (curl or chrome) it failed.

#return policy_string ... this is incorrect.
return json.loads(policy_string)
suman j
  • 6,710
  • 11
  • 58
  • 109
  • subtle and unclear in documentation, but this exact mistake, from a python lambda authorizer, just caught me out too - thanks for the clarification – Tom Bunting Apr 26 '18 at 10:38
  • For people still don't work, you might accessing the wrong header path in your authorizer script. Example: My Case: Wrong: event.headers.Authorization Actual: event.authorizationToken Full structure: { type: 'TOKEN', methodArn: 'arn:aws:execute-api:****', authorizationToken: 'Basic ****' } log your incoming and identify yours. – Bala Feb 03 '20 at 10:43
  • 1
    > Its strange that the same lambda function did not error when I tested the API from API Gateway "test" feature. This is because using the "test" feature bypasses the authorizer and calls the lambda directly. – ChrisDevWard Sep 15 '20 at 20:26
0

In my case i was not returning a properly formatted IAM policy document. My Authorizer function was doing wrong assumptions on how to get some parameters from request, and default result was not proper policy (this was my specific case). I managed to debug it using CloudWatch log service, with traditional logging instructions coming from my function code.

Jaime Casero
  • 371
  • 2
  • 6
0

Thanks @kashyap for this comment on another answer:

Not true. AuthorizerConfigurationException is for all Exceptions thrown during Authorizer execution, unless they're mapped using Gateway Response Mapping.

I think there's a good Q&A over here, so for my AuthorizerConfigurationException I needed exactly:

raise Exception("Unauthorized")
pzrq
  • 1,626
  • 1
  • 18
  • 24