Написание авторизаторов для безсерверных фреймворков на Ruby - PullRequest
2 голосов
/ 12 апреля 2019

Я пытаюсь написать авторизатор для защиты вызовов лямбды с помощью безсерверной инфраструктуры. Я использую 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? получит токен, а затем вернет политику, которая разрешит доступ к protected лямбда-функции. Я не совсем уверен, что входит в аргумент PrincipalId - у меня нет user.id.

Прямо сейчас он жалуется, что: seeker-dev-authorize is not authorized to perform: iam:CreatePolicy on resource: policy seeker-allowed, что приводит меня в замешательство: я не могу создать политику ... на политике? И где я должен установить это разрешение? На IAM или serverless.yml? Поскольку я установил разрешения для кодирования / декодирования ключей в безсерверном режиме, может быть, я должен сделать то же самое с этим?

1 Ответ

1 голос
/ 12 апреля 2019

Я раньше не пользовался пользовательскими авторизаторами, но я собрал небольшой проект 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

Обратите внимание, что я возвращаю хэш, а не строку с to_json, я получил ошибку от авторизатора при использовании to_json.

Также обратите внимание, что я использую event["methodArn"] для получения защищенного лямбда-ARN, использование context.invoked_function_arn также вызвало ошибку.

Кроме того, не включая заголовок авторизации в запросе, будет возвращено «Несанкционированная ошибка»:

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

Наконец, о principalId:

PrincipalId - обязательное свойство в вашем ответе авторизатора. Он представляет основной идентификатор вызывающего абонента. Это может варьироваться от приложения к приложению, но это может быть имя пользователя, адрес электронной почты или уникальный идентификатор.

Источник: https://www.alexdebrie.com/posts/lambda-custom-authorizers/

...