Функция AWS Lambda не может получить доступ к API AppSync GraphQL — отказано в разрешении

#amazon-web-services #aws-lambda #graphql #aws-appsync

#amazon-web-services #aws-lambda #graphql #aws-appsync

Вопрос:

У меня возникли проблемы с вызовом запроса AppSync GraphQL с помощью функции AWS Lambda. Я использовал код в этой статье, в частности, последнюю часть, в которой используются разрешения IAM: https://docs.amplify.aws/lib/graphqlapi/graphql-from-nodejs/q/platform/js#signing-a-request-from-lambda

 const https = require("https");
const AWS = require("aws-sdk");
const urlParse = require("url").URL;
const appsyncUrl = process.env.API_MYAPP_GRAPHQLAPIENDPOINTOUTPUT;
const region = process.env.REGION;
const endpoint = new urlParse(appsyncUrl).hostname.toString();
const graphqlQuery = require("./query.js").query;

exports.handler = async (event) => {
  const req = new AWS.HttpRequest(appsyncUrl, region);

  req.method = "POST";
  req.path = "/graphql";
  req.headers.host = endpoint;
  req.headers["Content-Type"] = "application/json";
  req.body = JSON.stringify({
    query: graphqlQuery,
    operationName: "list",
  });

  const signer = new AWS.Signers.V4(req, "appsync", true);
  signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate());

  const data = await new Promise((resolve, reject) => {
    const httpRequest = https.request({ ...req, host: endpoint }, (result) => {
      result.on("data", (data) => {
        resolve(JSON.parse(data.toString()));
      });
    });

    httpRequest.write(req.body);
    httpRequest.end();
  });

  return {
    statusCode: 200,
    body: data,
  };
}; 

Я использую CLI Amplify. Я использовал CLI для создания функции и обеспечения доступа к API GraphQL.

Конкретная ошибка, которую я получаю в лямбде, такова:

       {
  "statusCode": 200,
  "body": {
    "errors": [
      {
        "errorType": "UnauthorizedException",
        "message": "Permission denied"
      }
    ]
  }
}
 

GraphQL настроен на использование пула пользователей Cognito в качестве аутентификации, и я добавил IAM в качестве дополнительного механизма аутентификации через CLI Amplify. Консоль AWS GraphQL показывает, что у меня есть Cognito в качестве основного механизма аутентификации, а IAM — вторичный.

Похоже, что функция Lambda разрешена нормально, поскольку она показывает 4 ресурса (создание, обновление, удаление, чтение), соответствующие API, и разрешает: appsync:GraphQL в качестве действия.

Если я запускаю функцию локально, используя amplify mock function myfunction ее, она выполняется нормально, и результат запроса GraphQL возвращается правильно.

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

Таблица, к которой я обращаюсь, определена в моем schema.graphql как:

  type Business
  @model
  @auth(
    rules: [
      { allow: owner }
      { allow: groups, groups: ["Admin"] }
      { allow: private, provider: iam }
    ]
  ) {
  id: ID!
  owner: String!
  name: String!
  emailSuffix: String!
  shortCode: String!
}
 

Я удалил аутентификацию из модели, и это не имеет значения.

Я удалил функцию и заново создал ее на случай, если разрешения каким-то образом перепутались.

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

ОБНОВЛЕНИЕ Я внес изменения в политику разрешений внутри IAM Manager для политики amplify-lambda-execution, и это, похоже, устранило проблему.

Политика разрешений, первоначально добавленная Amplify, имела вид:

 arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/create/*
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/read/*
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/edit/*
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/delete/*
 

внесение изменений в:

 arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/*/fields/* 
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID
 

позволяет функции lambda выполнить и успешно выполнить запрос GraphQL в моей таблице. Похоже, это проблема с разрешениями, которые Amplify добавляет к функции. Перезапись вручную не является отличным решением.

Ответ №1:

Проблема возникла после установки — amplify cli «4.45.2». Старый код для автоматически создаваемых разрешений в шаблоне lambda cloudformation выглядел следующим образом.

             {
          "Effect": "Allow",
          "Action": [
            "appsync:Create*",
            "appsync:StartSchemaCreation",
            "appsync:GraphQL",
            "appsync:Get*",
            "appsync:List*",
            "appsync:Update*",
            "appsync:Delete*"
          ],
          "Resource": [
            {
              "Fn::Join": [
                "",
                [
                  "arn:aws:appsync:",
                  {
                    "Ref": "AWS::Region"
                  },
                  ":",
                  {
                    "Ref": "AWS::AccountId"
                  },
                  ":apis/",
                  {
                    "Ref": "myApiGraphQLAPIIdOutput"
                  },
                  "/*"
                ]
              ]
            }
          ]
        }
 

Но после того, как я перешел на усиление cli «4.45.2» и предоставил разрешения lambda для appsync.
Он сгенерировал :

     {
          "Effect": "Allow",
          "Action": [
            "appsync:GraphQL"
          ],
          "Resource": [
            {
              "Fn::Join": [
                "",
                [
                  "arn:aws:appsync:",
                  {
                    "Ref": "AWS::Region"
                  },
                  ":",
                  {
                    "Ref": "AWS::AccountId"
                  },
                  ":apis/",
                  {
                    "Ref": "myApiGraphQLAPIIdOutput"
                  },
                  "/types/create/*"
                ]
              ]
            },
            {
              "Fn::Join": [
                "",
                [
                  "arn:aws:appsync:",
                  {
                    "Ref": "AWS::Region"
                  },
                  ":",
                  {
                    "Ref": "AWS::AccountId"
                  },
                  ":apis/",
                  {
                    "Ref": "myApiGraphQLAPIIdOutput"
                  },
                  "/types/read/*"
                ]
              ]
            },
            {
              "Fn::Join": [
                "",
                [
                  "arn:aws:appsync:",
                  {
                    "Ref": "AWS::Region"
                  },
                  ":",
                  {
                    "Ref": "AWS::AccountId"
                  },
                  ":apis/",
                  {
                    "Ref": "myApiGraphQLAPIIdOutput"
                  },
                  "/types/update/*"
                ]
              ]
            }
          ]
        }


enter code here
 

И я получил сообщение об ошибке «отказано в разрешении» при попытке связаться с appsync из lambda.

Я думаю, что в новом cli есть какая-то ошибка при генерации разрешений appsync для lambda.

Я вручную вернулся к старому сгенерированному коду в файле lambda cloudformation, и это сработало.

Комментарии:

1. Спасибо, что поделились файлами формирования облака. Это полезно. Я использую 4.44.2 CLI Amplify. Я не обновился до 4.45.2. Должно быть, проблема с обеими версиями CLI. Обновление файла формирования облака вручную лучше, чем ручная настройка разрешений через пользовательский интерфейс.