AppSync 与 AWS4 和混合身份验证类型(UserPools 和 IAM)

Posted

技术标签:

【中文标题】AppSync 与 AWS4 和混合身份验证类型(UserPools 和 IAM)【英文标题】:AppSync with AWS4 and mixed authentication type (UserPools and IAM) 【发布时间】:2021-04-15 12:02:19 【问题描述】:

我定义了一个 AppSync GraphQL API。 API 使用 Cognito UserPools 作为主要身份验证。这部分工作正常。

我正在尝试使用 axiosaws4 执行来自 Nodejs Lambda 函数的请求。我试图命中的突变是在我的架构中配置这样的东西(省略大部分架构):

AppSyncSchema:
    Type: AWS::AppSync::GraphQLSchema
    Properties:
      ApiId: !GetAtt MyApi.ApiId
      Definition: |
        type Something 
          someId: ID!
        
        input SomethingInput 
          someId: ID!
        
        type Mutation 
          doSomething(input: SomethingInput!): Something @aws_iam
        
        

我已将 Lambda 函数执行角色配置为拥有appsync:GraphQL 权限:

"Action": [
  "appsync:GraphQL"
],
"Resource": "arn:aws:appsync:eu-west-2:xxxx:apis/yyyy/*",
"Effect": "Allow",
"Sid": "AllowAppSyncExecution"

从网上的不同文章中,我整理了一些请求,然后我的 Nodejs Typescript 函数会尝试执行:

 const doSomething = `mutation doSomething($input: SomethingInput!) 
    doSomething(input: $input) 
      someId
    
  `;

  const data = 
    operationName: 'doSomething',
    query: doSomething,
    variables: 
      input:  someId: 'abc' ,
    ,
  ;
  const body = JSON.stringify(data);

  const signOptions = 
    method: 'POST',
    url: 'https://zzzz.appsync-api.eu-west-2.amazonaws.com/graphql, 
    host: 'zzzz.appsync-api.eu-west-2.amazonaws.com',
    path: '/graphql',
    region: process.env.AWS_REGION,
    service: 'appsync',
    headers: 
      'content-type': 'application/json',
    ,
    body, // used by aws4
    data, // used by axios
  ;

  const creds = 
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    sessionToken: process.env.AWS_SESSION_TOKEN,
  ;

  const signed = aws4.sign(signOptions, creds);
  delete signed.headers.Host;
  delete signed.headers['Content-Length'];

  console.log(signed);
  console.log('Got signed headers');

  try 
    await axios(signed);
   catch (err) 
    console.error('Fialed to execute AppSync request', err);
    throw err;
  

我总是收到Request failed with status code 401 回复。 AppSync 日志没有透露更多信息:


    "logType": "RequestSummary",
    "requestId": "11111111",
    "graphQLAPIId": "some id",
    "statusCode": 401,
    "latency": 7079000

我在正确配置时缺少什么?是否需要添加一些内容以仅允许 AWS IAM 用于特定突变,或者您是否发现我尝试执行请求的方式有任何问题?

这些是我参考的文章:

manually-triggering-appsync-apollo-subscriptions

calling-amazon-api-gateway-authenticated-methods-with-axios-and-aws4

【问题讨论】:

【参考方案1】:

搞定了。我必须向AWS::AppSync::GraphQLApi 添加额外的身份验证提供程序。在 CloudFormation 中,这看起来像是一个附加属性:

  Type: AWS::AppSync::GraphQLApi
    Properties:
      Name: !Ref MyApi
      AuthenticationType: AMAZON_COGNITO_USER_POOLS
      UserPoolConfig:
        UserPoolId: !Ref MyPool
        AwsRegion: !Ref MyRegion
        DefaultAction: ALLOW
      AdditionalAuthenticationProviders:
        - AuthenticationType: AWS_IAM

完成这项工作后,我收到了来自 AppSync GraphQL 的响应,但它包含响应对象中所有字段的 GraphQL 错误:

Not Authorized to access someId on type Something

为了解决这个问题,我还必须在 GraphQL Schema 中允许这种类型的 IAM:

type Something @aws_cognito_user_pools @aws_iam 
  someId: ID!

【讨论】:

以上是关于AppSync 与 AWS4 和混合身份验证类型(UserPools 和 IAM)的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Amplify 配置为使用多个 AppSync 端点?

通过身份池联合的开发人员身份验证身份无法在 Amplify 项目中进行 AppSync 调用

具有公共/私有访问权限的 Appsync 身份验证,无需 AWS Cognito

通过 AppSync 上的自定义 Lambda 授权方对突变进行身份验证

验证 Apollo 客户端以使 AppSync 与 @aws_subscribe 一起使用

如何使用 python 调用具有 Cognito 身份验证的 AppSync 突变?