API 未调用网关授权器

API Gateway Authorizer is not being called

我创建了一些 Lambda 函数并使用 SAM 部署了它们。部署成功,但在尝试到达端点时我总是获得

{ message: "Unauthorized" }

即使我使用 Authentication header 发送正确的 Bearer 令牌。 然后,如果我去 Authorizer 并 运行 测试,它会很好地通过并在 CloudWatch 中生成日志,但是当我 运行 从我的前端应用程序或 REST 客户端应用程序到端点的请求时,我得到未经授权的消息并检查 CloudWatch,没有执行授权方功能。

此外,从 Lambda 配置中检查 Authorizer 函数,我可以看到 API Gateway Trigger 中有一个错误,但不知道它是什么意思。

我使用 AWS 提供的指南创建了授权函数:https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html#api-gateway-lambda-authorizer-lambda-function-create

共享我的 SAM 配置

Resources:
 SomeAPI:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      TracingEnabled: true
      Auth:
        DefaultAuthorizer: MyLambdaTokenAuthorizer
        Authorizers:
          MyLambdaTokenAuthorizer:
            FunctionArn: !GetAtt AuthorizerFunction.Arn

  GetActivityStreamFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: get-activity-stream/ 
      Handler: index.handler
      Layers:
        - !Ref DepencenciesLayer
        - !Ref DatabaseLayer
      Events:
        GetActivityStream:
          Type: Api
          Properties:
            RestApiId: !Ref SomeAPI
            Path: /activity-stream
            Method: get

  ## Authorizer Function
  AuthorizerFunction:
    Type: AWS::Serverless::Function
    Properties:
      Layers:
        - !Ref DepencenciesLayer
      CodeUri: authorizer/ 
      Handler: index.handler

关于授权者发回的响应,它发送了API网关

请求的所有参数
{
      principalId: decoded.sub,
      policyDocument: getPolicyDocument("Allow", params.methodArn),
      context: { scope: decoded.scope }
}

我使用的 运行time 是 nodejs12.x,这里是我从 AWS 控制台获得的一些屏幕截图。

在对互联网上发现的不同内容进行大量测试后,当我注意到政策文件有误时,我开始有所改进:

之前

  const policyDocument = {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": effect,
        "Action": "execute-api:Invoke",
        "Resource": resource
      }
    ]
  };

之后

  const policyDocument = {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": effect,
        "Action": [
          "execute-api:Invoke"
        ],
        "Resource": [
          resource
        ]
      }
    ]
  };

其中 ActionResource 应该是数组。此外,我将 resource 变量设置为 '*' 而不是 event.methodArn,因为在缓存授权时,缓存的策略仅匹配到达的第一个端点,而下一次调用其他端点会导致错误: user not authorized for the method requested.

其他更改在 template.yaml

Resources:
  SomeAPI:
    Type: AWS::Serverless::Api
      Auth:
        DefaultAuthorizer: MyLambdaTokenAuthorizer
        AddDefaultAuthorizerToCorsPreflight: false
        Authorizers:
          MyLambdaTokenAuthorizer:
            FunctionArn: !GetAtt AuthorizerFunction.Arn
            Identity:
              Header: Authorization
              ValidationExpression: Bearer.*

AddDefaultAuthorizerToCorsPreflightfalse 值进行预检调用(OPTIONS),无法验证,因为预检请求是由浏览器完成的,否则所有调用来自 Axios 也失败了。

我有同样的事情。 如果未调用授权方 Lambda,我认为这是因为缓存了身份验证或配置认为请求中没有身份 material。

看看 https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_authorizer#identity_source 设置:只有某些 headers 被认为包含身份 material,并且它们被用作缓存键