在 Ruby 中为无服务器框架编写授权程序

Writing authorizers for serverless framework in Ruby

我正在尝试编写一个授权程序来保护对使用无服务器框架的 lambda 的调用。我正在使用 Ruby.

配置:

provider:
  name: aws
  runtime: ruby2.5

  iamRoleStatements:
    - Effect: Allow
      Action:
      - KMS:Decrypt
      Resource: ${self:custom.kmsSecrets.keyArn}

functions:
  authorize:
    handler: handler.authorize
  hello:
    handler: handler.protected
    events:
      - http:
          path: protected
          method: get
          authorizer: authorize

授权人:

def authorize(event:, context:)
  if is_authorized?
    {
      "policyDocument": {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Action": "execute-api:Invoke",
            "Resource": [ context.invoked_function_arn ],
            "Effect": "Allow"
          }
        ]
      },
      "principalId": "seeker"
    }.to_json
  end
end

我想实现的身份验证是基于令牌的:is_authorized? 方法将接收令牌,然后 return 允许访问 protected lambda 函数的策略. 我不完全确定 PrincipalId 参数中的内容 - 我没有 user.id.

现在它抱怨说:seeker-dev-authorize is not authorized to perform: iam:CreatePolicy on resource: policy seeker-allowed 这让我很困惑:我不能创建一个策略......关于这个策略?我应该在哪里设置此权限?在 IAMserverless.yml 上?因为我已经在无服务器中将权限设置为 encode/decode 键,也许我应该对此做同样的事情?

我以前没有使用过自定义授权器,但我整理了一个小的 hello world 项目来尝试一下,这就是我的发现。

受保护函数和授权函数:

def authorize(event:, context:)
  {
    "principalId": "test",
    "policyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": "execute-api:Invoke",
          "Effect": "Allow",
          "Resource": event["methodArn"]
        }
      ]
    }
  }
end

def hello(event:, context:)
  { statusCode: 200, body: JSON.generate('This is a protected endpoint!') }
end

请注意,我 return 使用 to_json 使用散列而不是字符串,我在使用 to_json.

时收到授权方返回的错误

另请注意,我使用 event["methodArn"] 获取受保护的 lambda ARN,使用 context.invoked_function_arn 也导致我出错。

除此之外,在请求中不包括授权 header,将 return 一个 "Unauthorized error":

curl -X GET https://endpoint/dev/hello -H 'Authorization: test'

最后,关于principalId

The principalId is a required property on your authorizer response. It represents the principal identifier for the caller. This may vary from application-to-application, but it could be a username, an email address, or a unique ID.

来源:https://www.alexdebrie.com/posts/lambda-custom-authorizers/