AWS API Шлюз пользовательский авторизатор странно показывает ошибку

Вот контекст:

  • Я настроил ресурс в шлюзе API./Пользователь/компании
  • У этого ресурса есть 2 метода. Получить и ПОСТ.
  • Я настроил собственный Authorizer для этого ресурса.

Эта проблема:

  • Я могу вызвать метод GET, отправив правильную информацию об авторизации, и я получу результаты, как и ожидалось.
  • Я пытаюсь отправить запрос POST и получаю следующую ошибку:

{
  "message": "User is not authorized to access this resource"
}

Ответ 1

Это можно исправить с помощью двух вариантов, которые описаны в ошибочном ответе: https://forum.serverless.com/t/rest-api-with-custom-authorizer-how-are-you-dealing-with-authorization-and кэш- под политикой /3310

Укороченная версия:

  1. Установите TTL для авторизатора клиента на 0
  2. Установить пользовательский ресурс политики авторизатора как "*"

Опробовал оба решения, и они решили проблему с "Пользователь не авторизован для доступа к этому ресурсу" для меня.

Ответ 2

Эта ошибка будет возникать, если вы используете event.methodArn в качестве ресурса для сгенерированной политики и совместно используете авторизатор между различными функциями из-за того, как работает кэширование политики. Для предоставленного токена он кэширует политику по всему API, это будет одна и та же запись кэша для всех методов и ресурсов в одном и том же API и этапе (если они совместно используют один и тот же авторизатор).

Например, при отправке запроса GET/users ARN будет выглядеть примерно так:

arn:aws:execute-api:us-1:abc:123/prod/GET/users

При следующем вызове любой конечной точки с таким же токеном аутентификации будет использоваться кэшированная политика, которая была создана при первом вызове GET/users. Проблема с этой кэшированной политикой заключается в том, что для этого ресурса разрешен только один конкретный ресурс arn:.../prod/GET/users, любой другой ресурс будет отклонен.

В зависимости от того, насколько вы хотите ограничить разрешения политики, вы можете указать любой возможный ресурс при создании политики.

{
  "principalId": "user",
  "policyDocument": {
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow",
        "Resource": [
          "arn:aws:execute-api:us-1:abc:123/prod/GET/v1/users",
          "arn:aws:execute-api:us-1:abc:123/prod/POST/v1/users",
          "arn:aws:execute-api:us-1:abc:123/prod/GET/v1/orders"
        ]
      }
    ],
    "Version": "2012-10-17"
  }
}

или используйте подстановочные знаки

"Resource": "arn:aws:execute-api:us-1:abc:123/prod/*/v?/*"

или даже

"Resource": "*"

Вы можете использовать переменные политики для некоторых расширенных шаблонов.

Можно также использовать подход черного списка, разрешив все с использованием подстановочных знаков, а затем запретив определенные ресурсы в другом заявлении политики.

Источники:

Ответ 3

При использовании пользовательского кода построения политики модуль js узла aws-auth-policy Часть Nodejs, которую вы можете использовать,

AuthPolicy.prototype.allowAllMethods = function () {
  addMethod.call(this, "allow", "*", "*", null);
}

В коде

const AuthPolicy = require('aws-auth-policy');
  const policy = new AuthPolicy(principalId, awsAccountId, apiOptions);
           // policy.allowMethod(method, resource);
            policy.allowAllMethods();
            const authResponse = policy.build();

Ответ 4

Я исправил это, установив AuthorizerResultTtlInSeconds в 0.

Причина этого в том, что я использовал общий авторизатор. Однако авторизатор работал, читая контекст события запроса и предоставляя IAM для последующего вызова определенной лямбды.

Поскольку автором был предоставлен общий доступ, он кэшировал ответ, который представлял собой IAM для конкретной лямбды для TTL (в моем случае) 300 секунд.

Поэтому я мог бы вызвать один API одну минуту, а не следующую.

Изменение значения выше на 0 решило проблему.