custom authorizers in Amazon API Gateway 500 error
Asked Answered
D

2

8

I use Serverless-Authentication-boilerplate and want to map custom error response. But it always return 500 error.

authorize.js

// Authorize
function authorize(event, callback) {
  let providerConfig = config(event);
  try {
    let data = utils.readToken(event.authorizationToken, providerConfig.token_secret);
    console.log("Decrypted data: " + JSON.stringify(data));

    let methodArn = event.methodArn.replace(/(GET|POST|PUT|DELETE)/g, '*').replace(/mgnt.+/g, 'mgnt/*');

    console.log(`Change methodArn to: ${methodArn}`);

    // TODO: handle expiration time validation
    callback(null, utils.generatePolicy(
      data.id, // which is $context.authorizer.principalId
      'Allow',
      methodArn));
  } catch (err) {
    console.log(err);
    callback('401 Unauthenticated');
  }
}

s-function.json

responses:{ 
  "401 Unauthenticated.*": {
      "statusCode": "401"
  },
  "default": {
      "statusCode": "200",
      "responseModels": {
        "application/json;charset=UTF-8": "Empty"
      },
      "responseTemplates": {
        "application/json;charset=UTF-8": ""
      }
  }
}
Discordance answered 29/7, 2016 at 3:25 Comment(0)
D
12

After ask to Amazon Web Services.

Unfortunately the mapping of the Authorizer is not currently configurable and every returned error from a lambda function will map to a 500 status code in API gateway. Moreover, the mapping is performed on an exact string match of the output, so, in order to return the intended 401 Error to the client, you should execute a call to 'context.fail('Unauthorized');.

Finally, I change

callback('401 Unauthenticated');

to

context.fail('Unauthorized');

and work fine.

Sharing to whom may encounter this.

Discordance answered 29/7, 2016 at 3:25 Comment(7)
Is this documented anywhere in AWS?Sven
Here REFDiscordance
I couldn't find the fail() method in the documentation you linked to, however I did find it here. The documentation states We recommend you use the callback, so it appears it is outdated, however I don't see a better solution to return a 401 at the moment.Gypsum
The problem is that context.fail('Unauthorized'); leads to a failed execution of the lambda. And when you have an Alarm that gets triggered on every failed execution of a lambda, you will receive notifications for each Unauthorized request. This could be an expired token, which is fine and should not lead to an failed lambda execution.Gabbard
Adding this does work but I then get the warning Warning: Auth function 'authorizer' returned a promise and also uses a callback! Is there any Promise safe way of doing this?Goebel
Please don't post links to AWS documentation. It's always useless.Matz
Web archive version from Jim's REF: web.archive.org/web/20160215214818/http://docs.aws.amazon.com/…Podagra
A
0

If your custom auth lambda is not able to return the policy document, your APIs will return 500 error.

Use async await properly to get the right response. (Assuming your code is in Node.js)

The code I was trying to execute was returning before promises getting fulfilled. You have to make sure that the code returns after the promises are fulfilled only.

Test the authorizer from the test feature of API authorizers to get the exact error causing your custom authorizer API gateway pair to fail.

Arsis answered 24/4 at 10:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.