【问题标题】:Serverless my custom authorizer is not working无服务器我的自定义授权器不起作用
【发布时间】:2022-01-30 23:59:45
【问题描述】:

我有以下 serverless.yaml:

    getSth: 
        handler: src/handlers/getSth.getSth
        events:
            - http:
                path: getSth
                method: get
                cors: true
                private: true
                authorizer: authorizerFunc
    authorizerFunc:
        handler: src/handlers/authorizer.authorizer

getSth 处理程序:

    module.exports.getSth = async (event, context) => {
    const response = {
        statusCode: 200,
        body: JSON.stringify({message: "nice you can call this});
    }
    return response;
    }

authorizerFunc:

    module.exports.authorizer = async (event, context) => {
         console.log('i will fail your authorization');
         let response = {
         isAuthorized: false,
         context: {
           stringKey: "value",
           numberKey: 1,
           booleanKey: true,
           arrayKey: ["value1", "value2"],
           mapKey: { value1: "value2" },
    },
  };
  return response;
}

尽管授权方不应允许执行该 getSth 函数,但仍会导致响应 200。控制台日志“我将无法通过您的授权”也未记录。

我做错了什么?

【问题讨论】:

  • 您好,您可以共享getSthauthorizerFunc 的CloudWatch 日志吗?
  • 从您的yaml 看来,您正在部署一个 REST Api(即 API Gateway V1),但这种形式的授权函数适用于 HTTP Api(即 API Gateway V2)。对于 REST API,您的授权方 lambda 必须返回 IAM 策略。请参阅docs.aws.amazon.com/apigateway/latest/developerguide/…aws.amazon.com/de/blogs/compute/…
  • 您是否在 AWS 控制台中检查了授权方实际上已附加到您的函数?

标签: amazon-web-services aws-lambda serverless aws-serverless


【解决方案1】:

我已尝试分析您的代码并找到几个可以开始挖掘的点。

私有函数

private: true 的密钥实际上使 API Gateway 需要一个 API 密钥。我现在没有尝试自己,但也许private: true 和授权人不会一起去。

奇怪的是,你可以调用这个函数。你如何调用函数?通过 CLI 还是通过 API Gateway 和 API 测试工具(例如 Postman 或 Insomnia)?

授权人配置

您的授权人配置绝对正确。我们的代码中确实有相同的设置。

授权者事件

一个授权函数得到一个APIGatewayTokenAuthorizerEvent 并且应该回复一个APIGatewayAuthorizerResult。后者看起来很像 IAM 语句,我们不使用字段 isAuthorized: false 根据您的示例。我不明白这个领域是从哪里来的。我们允许请求的结果或多或少类似于以下内容:

{
  "principalId": "<our auth0 user-id>",
  "policyDocument": {
    "Version": "2012-10-17",
    "Statement": [{
      "Action": "execute-api:Invoke",
      "Effect": "Allow",
      "Resource": "*"
    }]
  }
}

注意principalId 字段如何引用我们从身份提供者 (Auth0) 获得的用户名。实际上看起来像这样:auth0|6f84a3z162c72d0d0d000a00

此外,我们可以通过Effect 字段允许或拒绝函数调用,该字段可以保存值AllowDeny

最后,您可以指定允许调用者调用哪个资源。为了简单起见,我将* 放在那里。当然,在现实世界中,您可以从事件和上下文中提取被调用函数的 ARN,并将其传递到策略文档中。

意见

我们也很难通过 AWS 的文档来解决这个问题。当然,对于 AWS,首选的集成是通过 AWS Cognito(我也更喜欢它,因为它的集成更加简化。我们在这里使用 TypeScript 受益匪浅,我们使用它来强制输入和输出无服务器函数的类型。这样就很容易弄清楚响应应该是什么样子。

背景

我们使用自定义授权器集成来允许 Auth0 中已经存在的用户群通过应用程序客户端或单页应用程序使用我们基于无服务器的 API。

【讨论】:

    猜你喜欢
    • 2020-05-28
    • 2015-01-23
    • 2020-03-16
    • 2022-12-17
    • 1970-01-01
    • 2019-05-01
    • 2019-12-23
    • 2021-03-13
    • 2022-07-30
    相关资源
    最近更新 更多