未调用API网关授权者

时间:2020-03-30 20:22:34

标签: amazon-web-services aws-lambda authorization aws-api-gateway

我创建了一些Lambda函数,并使用SAM进行了部署。部署成功,但是当尝试到达端点时,我总是会得到

{ message: "Unauthorized" }

即使我使用Authentication标头发送了正确的Bearer令牌。 然后,如果我去授权者并运行测试,它通过得很好并且在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 }
}

我正在使用的运行时是nodejs12.x,下面是从AWS控制台获得的一些屏幕截图。

Testing the Authorizer

Checking the API endpoint config

Error showed on Lambda console

2 个答案:

答案 0 :(得分:0)

经过大量时间的测试,我发现政策文件有误后,我开始进行改进:

之前

  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.*
值为AddDefaultAuthorizerToCorsPreflight

false进行预检调用(OPTIONS),因此无法验证,因为预检请求是由浏览器完成的,否则来自{{1 }}也失败。

答案 1 :(得分:0)

我有同样的事情。 如果未调用授权者Lambda,则可能是因为缓存了auth或配置认为请求中没有身份信息。

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