无法使用IAM和appsyncclient从lambda中验证appsync graphql api

发布于 2025-01-30 17:29:35 字数 3109 浏览 1 评论 0原文

我正在使用Amplify堆栈,需要对我的GraphQL API执行一些操作,该API背后有DynamoDB。我的lambda函数中的请求返回一个未经授权的错误:“未授权在type sourceSync上访问getSourcesync”,其中getSourcesync是gql Query Query,sourceSync是模型名称。

我的schema.grapqhl对于此特定模型的设置如下。注意Auth规则允许私人提供者IAM:

type SourceSync @model (subscriptions: { level: off }) @auth(rules: [
    {allow: private, provider: iam}
    {allow: groups, groups: ["Admins"], provider: userPools},
    {allow: groups, groups: ["Users"], operations: [create], provider: userPools},
    {allow: groups, groupsField: "readGroups", operations: [create, read], provider: userPools},
    {allow: groups, groupsField: "editGroups", provider: userPools}]) {
    id: ID! @primaryKey
    name: String
    settings_id: ID @index(name: "bySettingsId", queryField: "sourceSyncBySettingsId")
    settings: Settings @hasOne(fields: ["settings_id"])
    childLookup: String
    createdAt: AWSDateTime!
    updatedAt: AWSDateTime!
    _createdBy: String
    _lastChangedBy: String
    _localChanges: AWSJSON
    readGroups: [String]
    editGroups: [String]
}

我的lambda函数的角色具有以下内联策略。 (在本文中为安全目的省略了实际ID值):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "appsync:GraphQL"
            ],
            "Resource": [
                "arn:aws:appsync:us-east-1:111myaccountID:apis/11mygraphqlapiID/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "appsync:GetType"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        }
    ]
}

最后,我的lambda函数设置为如下,并在一个简单的查询测试中设置:

/* stuff */

"use strict";
const axios = require("axios");
const awsAppSync = require("aws-appsync").default;
const gql = require("graphql-tag");
require("cross-fetch/polyfill");
const { PassThrough } = require("stream");
const aws = require("aws-sdk");

aws.config.update({
    region: process.env.AWS_REGION,

});

const appSync = new aws.AppSync();

const graphqlClient = new awsAppSync({
    url: process.env.API_GRAPHQLAPIENDPOINTOUTPUT,
    region: process.env.AWS_REGION,
    auth: {
        type: "AWS_IAM",
        credentials: aws.config.credentials,
    },
    disableOffline: true
});

exports.handler = async (event, context) => {
    
    console.log('context :: '+JSON.stringify(context));
    
    console.log('aws config :: '+JSON.stringify(aws.config));
    
          const sourceSyncTypes = await appSync
          .getType({
            apiId: process.env.API_GRAPHQLAPIIDOUTPUT,
            format: "JSON",
            typeName: "SourceSync",
          })
          .promise();
          console.log('ss = '+JSON.stringify(sourceSyncTypes));
    
    try {
    const qs = gql`query GetSourceSync {
  getSourceSync(id: "ov3") {
    id
    name
  }
}`;
    const res = await graphqlClient.query({query: qs, fetchPolicy: 'no-cache'});
    console.log(JSON.stringify(res));
    
    }
    catch(e) {
        console.log('ERR :: '+e);
        console.log(JSON.stringify(e));
    }
    
};

I'm using an amplify stack and need to perform some actions to my graphql api which has dynamodb behind it. The request in my lambda function returns an Unauthorized error: "Not Authorized to access getSourceSync on type SourceSync", where getSourceSync is the gql query and SourceSync is the model name.

My schema.grapqhl for this particular model is set up as following. Note auth rule allow private provider iam:

type SourceSync @model (subscriptions: { level: off }) @auth(rules: [
    {allow: private, provider: iam}
    {allow: groups, groups: ["Admins"], provider: userPools},
    {allow: groups, groups: ["Users"], operations: [create], provider: userPools},
    {allow: groups, groupsField: "readGroups", operations: [create, read], provider: userPools},
    {allow: groups, groupsField: "editGroups", provider: userPools}]) {
    id: ID! @primaryKey
    name: String
    settings_id: ID @index(name: "bySettingsId", queryField: "sourceSyncBySettingsId")
    settings: Settings @hasOne(fields: ["settings_id"])
    childLookup: String
    createdAt: AWSDateTime!
    updatedAt: AWSDateTime!
    _createdBy: String
    _lastChangedBy: String
    _localChanges: AWSJSON
    readGroups: [String]
    editGroups: [String]
}

My lambda function's role has the following inline policy attached to it. (Actual ID values have been omitted for security purposes on this post):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "appsync:GraphQL"
            ],
            "Resource": [
                "arn:aws:appsync:us-east-1:111myaccountID:apis/11mygraphqlapiID/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "appsync:GetType"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        }
    ]
}

And finally my lambda function is set up as follows with a simple query test:

/* stuff */

"use strict";
const axios = require("axios");
const awsAppSync = require("aws-appsync").default;
const gql = require("graphql-tag");
require("cross-fetch/polyfill");
const { PassThrough } = require("stream");
const aws = require("aws-sdk");

aws.config.update({
    region: process.env.AWS_REGION,

});

const appSync = new aws.AppSync();

const graphqlClient = new awsAppSync({
    url: process.env.API_GRAPHQLAPIENDPOINTOUTPUT,
    region: process.env.AWS_REGION,
    auth: {
        type: "AWS_IAM",
        credentials: aws.config.credentials,
    },
    disableOffline: true
});

exports.handler = async (event, context) => {
    
    console.log('context :: '+JSON.stringify(context));
    
    console.log('aws config :: '+JSON.stringify(aws.config));
    
          const sourceSyncTypes = await appSync
          .getType({
            apiId: process.env.API_GRAPHQLAPIIDOUTPUT,
            format: "JSON",
            typeName: "SourceSync",
          })
          .promise();
          console.log('ss = '+JSON.stringify(sourceSyncTypes));
    
    try {
    const qs = gql`query GetSourceSync {
  getSourceSync(id: "ov3") {
    id
    name
  }
}`;
    const res = await graphqlClient.query({query: qs, fetchPolicy: 'no-cache'});
    console.log(JSON.stringify(res));
    
    }
    catch(e) {
        console.log('ERR :: '+e);
        console.log(JSON.stringify(e));
    }
    
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮萍、无处依 2025-02-06 17:29:35

找到了解决方案,在允许函数访问GraphQL API之后,似乎存在一个问题。但是,有一个区别要注意:

  1. 如果GraphQl API是Amplify App堆栈的一部分,则仅通过该应用程序的Amplify CLI创建的函数(例如:ex:ex: amplify add add add function ),并且通过那里可以访问API,将能够访问API。

    • 在更新期间,当您创建或更新功能以授予其权限时,您必须确保在放大推动操作期间,API堆栈还将更新。您可以通过简单地在Amplify/backend/api // schema.graphql文件中的注释中添加或删除空间来触发此触发。
  2. 如果直接通过AWS控制台创建了“ ADHOC”,但是它正在尝试访问作为Amplify App stack创建的GraphQL API,那么您将需要在Amplify/Backend中添加该函数的角色/api/< apiname>/custom-roles.json格式

      { 
      “ AdminRoleNames”:[< cool Name>“,”<角色名称2>“,...] 
    }
     

文档中参考参考在这里

  1. 如果您的API或LAMBDA函数都不是用Amplify CLI作为应用程序堆栈的一部分而创建的,那么只需要访问GraphQL资源以查询,突变和订阅Lambda在IAM中的角色,通过内联策略或Pre-Pre-pre-pre-定义的政策。

Found the solution, there seems to be an issue with triggering a rebuild of the resolvers on the api after permitting a function to access the graphql api. However there is a distinction to note:

  1. If the graphql api is part of an amplify app stack, then only functions created through the amplify cli for that app (ex: amplify add function) and that are given access to the api through there will be able to access the api.

    • additonally during the update when you either create, or update the function to give it permissions, you must ensure that during the amplify push operation, the api stack will also be updating. you can trigger this by simply adding or removing a space in a comment inside of your amplify/backend/api//schema.graphql file.
  2. If the function was created "adhoc" directly through the aws console, but it is trying to access a graphql api that was created as part of an amplify app stack, then you will need to put that function's role in amplify/backend/api/< apiname>/custom-roles.json in the format

    { 
      "adminRoleNames": ["<role name>", "<role name 2>", ...] 
    }
    

Documentation references here.

  1. If neither your api or lambda function were created with the amplify cli as part of an app stack, then just need to give access to the graphql resources for query, mutation and subscription to the lambda's role in IAM, via inline policies or a pre-defined policy.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文