如何使用 IAM 身份验证限制 Amplify Graphql API 中的访问?

问题描述 投票:0回答:2

我的 GraphQL API:

type MyEntity @model @auth(rules: [
      { allow: owner, ownerField: "ownerId"}
    ]) {
  id: ID!
  ownerId: String!
  strFld: String!
}

现在,我想要一个 lambda(“myLambda”)来查询

MyEntity
。因此,我将
{ allow: private, provider: iam }
添加到
MyEntity
,这允许 lambda 查询它(遵循 这些说明 进行 IAM 身份验证)。然而,除了允许 myLambda 访问
MyEntity
之外,它基本上绕过了所有者保护,并允许任何通过 IAM 连接的客户端编辑任何其他所有者的
MyEntity

例如,我没有做任何特别的事情来授予我的 React 客户端 IAM 访问权限,它通常通过用户组查询

MyEntity
。但是,只需将 React 客户端中的 graphql 查询更改为使用 GRAPHQL_AUTH_MODE.AWS_IAM,现在它就可以读取和写入 any
MyEntity
,无论所有者如何。

对实体使用 IAM 身份验证时,如何限制它以便只有我的 lambda 可以访问?文档说诸如“IAM 可用于管理访问”之类的内容,但它们没有解释我可以编辑以删除访问的外部(例如,react)客户端将使用什么角色/策略/等。

amazon-web-services aws-amplify aws-appsync aws-amplify-cli
2个回答
1
投票

经过一番挣扎后,我想我明白了。

为了使 lambda 能够调用 Amplify GraphQL API,您需要在 API 中添加身份验证规则,如

{ allow: private, provider: iam }
。您还可以执行
amplify function update
并授予您的函数调用 API 的权限,这将更新该 lambda 的执行角色以有权调用 API。

但是,在 API 中添加 auth 规则还有另一个效果:如果您使用 Cognito 身份验证,它还会将调用 API 的权限添加到身份池使用的“authRole”,这意味着任何登录的用户现在可以进行 IAM 查询来访问此 API。

我不想这样——我试图只授予对 lambda 的访问权限,而不是整个世界。事实上,我不希望我的 Cognito 用户进行任何 IAM 查询(他们应该只使用用户池身份验证),因此我创建了一个额外的空角色并修改了我的身份池以将其用作其 authRole。不幸的是,这是一个巨大的痛苦。我必须为角色创建一个自定义资源,然后覆盖 amplify auth涉及在打字稿中编写 CDK 代码,当它第一次不编译时很难排除故障(编译会生成非常模糊的编译器错误)。

但无论如何,这似乎有效。这就是我所做的:

amplify custom add
为我的空角色添加新资源:

  "IdentityPoolAuthRole": {
    "Type": "AWS::IAM::Role",
    "Properties": {
      "RoleName": {
        "Fn::Sub": [
          "(myapp)IdentityPoolAuthRole-${env}",
          {
            "env": {
              "Ref": "env"
            }
          }
        ]
      },
      "AssumeRolePolicyDocument": {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
                "Federated": "cognito-identity.amazonaws.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringLike": {
                    "cognito-identity.amazonaws.com:amr": "authenticated"
                }
            }
          }
        ]
      }
    }
  }

注意:理想情况下,该角色会在其 AssumeRolePolicyDocument 中指定身份池 ID,但这会导致不同环境中的不同身份池出现问题。

然后,

amplify override auth
并将其放入 override.ts 中:

import { AmplifyAuthCognitoStackTemplate, AmplifyProjectInfo } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyAuthCognitoStackTemplate, amplifyProjectInfo: AmplifyProjectInfo) {
  resources.identityPoolRoleMap.roles["authenticated"] = "(arn of the role created above)-" + amplifyProjectInfo.envName;
}

在我看来,这是一个问题,一旦你授予 lambda 调用放大 API 的权限,就很难保证它的安全。

不幸的是与此相关的放大说明没有提及这一点。


0
投票

允许:私人/公共非常令人困惑......可能应该是: 允许: guest/loggedInUser/serviceUser 或类似的东西...

© www.soinside.com 2019 - 2024. All rights reserved.