7

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": ""
      }
  }
}
Jim
  • 1,550
  • 3
  • 20
  • 34

1 Answers1

11

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.

Jim
  • 1,550
  • 3
  • 20
  • 34
  • 1
    Is this documented anywhere in AWS? – Noel Llevares Dec 19 '16 at 00:33
  • 1
    Here [REF](http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html) – Jim Feb 18 '17 at 05:09
  • I couldn't find the `fail()` method in the documentation you linked to, however I did [find it here](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-using-old-runtime.html#nodejs-prog-model-oldruntime-context-methods). 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. – mb-ca Mar 20 '18 at 12:43
  • 4
    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. – VolkerK Jul 20 '18 at 09:26
  • 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? – MoshMcCabe Feb 28 '20 at 15:26
  • Please don't post links to AWS documentation. It's always useless. – shredding Jun 03 '20 at 09:06
  • Web archive version from Jim's REF: https://web.archive.org/web/20160215214818/http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html – pzrq Aug 17 '23 at 06:31