无法在API网关中使用自定义授权程序

时间:2017-10-01 21:23:00

标签: node.js amazon-web-services aws-lambda aws-api-gateway

我有几天尝试使用auth0服务使用自定义授权程序保护我的API网关。我有我的lambda验证我的持票人令牌,如果我在AWS控制台内调用它,Lambda会工作,当我创建自定义授权器时,我可以使用Bearer令牌成功测试。

当我尝试将授权程序附加到我的API网关方法并使用邮递员和auth0提供的令牌测试请求时,它总是返回401状态代码。我在CloudWatch中读取了我的日志,并且每当我发出HTTP请求时,它都不会触发授权Lambda。我正在关注本教程: https://auth0.com/docs/integrations/aws-api-gateway/custom-authorizers/

这是我的授权lambda代码:

处理程序:

'use strict';

let jwtManager = require("./jwt_manager");

module.exports.authenticate = (event, context, callback) => {

  jwtManager.validate(event, function (error, data) {
    if (error) {
      if (!error) {
        context.fail("Unhandled error");
      }
      context.fail(error);
    }
    else {
      console.log("SUCCEED");
      context.succeed(data);
    }
  });

};

这是jwtManager:

"use strict";
require("dotenv").config({ silent: true });

let jwksClient = require("jwks-rsa");
let jwt = require("jsonwebtoken");

module.exports.validate = function(params, callback) {
  var token = validateParams(params);

  var client = jwksClient({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 10,
    jwksUri: process.env.JWKS_URI
  });

  var decodedJwt = jwt.decode(token, { complete: true });
  var kid = decodedJwt.header.kid;

  client.getSigningKey(kid, function(error, data) {
    if (error) {
        console.log(error);
      callback(error);
    } else {
      var signingKey = data.publicKey || data.rsaPublicKey;
      jwt.verify(
        token,
        signingKey,
        { audience: process.env.AUDIENCE, issuer: process.env.ISSUER },
        function(error, decoded) {
            if (error) {
                console.log("ERROR");
                console.log(error);
                callback(error);
            }
            else {
                console.log(decoded);
                var response = {
                    principalId: decoded.sub,
                    policyDocument: getPolicyDocument("Allow", params.methodArn),
                    context: {
                        scope: decoded.scope
                    }
                }
                console.log(response);
                console.log(response.policyDocument);
                callback(null, response);
            }
        }
      );
    }
  });
};

function validateParams(params) {
  var token;

  if (!params.type || params.type !== "TOKEN") {
    throw new Error("Expected 'event.type' parameter to have value TOKEN");
  }

  var tokenString = params.authorizationToken;
  if (!tokenString) {
    throw new Error("Expected 'event.authorizationToken' parameter to be set");
  }

  var match = tokenString.match(/^Bearer (.*)$/);
  if (!match || match.length < 2) {
    throw new Error(
      "Invalid Authorization token - '" +
        tokenString +
        "' does not match 'Bearer .*'"
    );
  }

  return match[1];
}

 function getPolicyDocument(effect, resource) {

    var policyDocument = {};
    policyDocument.Version = '2012-10-17'; // default version
    policyDocument.Statement = [];
    var statementOne = {};
    statementOne.Action = [ 'execute-api:Invoke', 'lambda:Invoke'] ; // default action
    statementOne.Effect = effect;
    statementOne.Resource = resource.split('/')[0] + '/*';
    policyDocument.Statement[0] = statementOne;
    return policyDocument;
}

提前致谢!

3 个答案:

答案 0 :(得分:2)

我想描述一下我是如何解决这个问题的。

首先,自定义授权程序始终需要在authorizationToken字段中使用承载令牌,但是在从Postman或任何其他客户端调用API网关时,您可以发送“承载令牌”#39;在授权标头中,由于这是行业标准,AWS已经支持它。

这里的诀窍在于令牌源&#39;在配置“自定义授权程序”时#39;我在这里附上了一张图片,您可以在其中配置“令牌源”#39;此字段描述自定义授权程序的输入来自“授权标题”。 enter image description here 这样,您仍然可以在“授权”中发送令牌。来自邮递员的标题,API网关将从“授权”中复制它。标题并将其复制到&#39; authorizationToken&#39;调用自定义授权程序lambda时输入字段。

enter image description here 希望它清楚。如果您需要更多详细信息,请与我们联系。

答案 1 :(得分:1)

当您使用自定义授权程序测试API网关但从未触发auth lambda函数时,可能是由于令牌标头名称/令牌模式验证中的验证失败。

我能够重现您的问题。

只有从#34;授权&#34;更改标题名称后,才能触发授权程序。 to&#34; AuthorizationToken&#34;在POSTMAN。

check the token header name I made the authorizer works

我认为这可能是AWS门户中的一个新错误,因为我注意到他们不久前已经更改了UI以配置API网关授权人。

非常奇怪的是,HTTP请求必须在名称为&#34; AuthorizationToken&#34;的标头中发送承载令牌。如果您的AWS计划允许您访问其技术支持,则应提醒他们此问题。

答案 2 :(得分:0)

在我的情况下,同样的错误(lambda未触发,授权失败)是由于我尚未部署API所致。我可能是错的,但似乎为了测试授权者,您的API必须至少部署一次。

因此,我部署了API,授权者测试开始起作用。