如何从AWS Lambda将用户添加到Cognito用户池组?

5
我正在尝试从一个被触发的Lambda函数中,将用户a添加到Cognito用户池组中。以下是该Lambda函数的代码:

    export async function postAuth(event, context, callback) {
      var AWS = require('aws-sdk');
      var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'});
  
      var params = {
        GroupName: process.env.S3_GROUP_NAME,
        UserPoolId: event.userPoolId,
        Username: event.userName
      };

      cognitoidentityserviceprovider.adminAddUserToGroup(params, function(err, data) {
        if (err) console.log("Error");
        else     console.log("Success");
      });
  
      console.log("Executed.");

      context.succeed(event);

    }

我知道这个lambda被触发了,因为我可以在CloudWatch上看到“executed”的日志。然而,调用adminAddUserToGroup似乎根本没有通过,因为既没有错误消息也没有成功消息被记录下来。
我尝试做这件事的原因是为了授予组不同的角色来访问后端资源。例如,我可以有一个名为Admin的组,具有CanWriteToS3角色,还可以有一个名为Customer的组,具有CanReadFromS3角色,并根据需要添加或删除用户到组中。
我怀疑这个lambda的一个问题是它缺少正确的权限来添加和删除用户到组中。
这是附加到lambda的角色:
    GroupManagementRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: GroupManagementRole
        AssumeRolePolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal:
                Service: [lambda.amazonaws.com]
              Action: sts:AssumeRole
        Policies:
          - PolicyName: "GroupManagementPolicy"
            PolicyDocument:
              Version: "2012-10-17"
              Statement:
                - Effect: Allow
                  Action:
                    - logs:CreateLogGroup
                    - logs:CreateLogStream
                    - logs:PutLogEvents
                  Resource: 
                    - 'Fn::Join':
                      - ':'
                      -
                        - 'arn:aws:logs'
                        - Ref: 'AWS::Region'
                        - Ref: 'AWS::AccountId'
                        - 'log-group:/aws/lambda/*:*:*'
                - Effect: "Allow"
                  Action: ["cognito-idp:AdminAddUserToGroup", "cognito-idp:AdminRemoveUserFromGroup"]
                  Resource:
                    Fn::Join:
                       - ""
                       - - "arn:aws:cognito-idp:us-east-1:XXXXXXXXXXX:userpool/us-east-1_XXXXXXX/*"

我不确定是否应该使用Cognito用户池的ARN作为资源,但我已经在网上搜索了很久,没有找到任何有关Cognito用户池组ARN的文档。

无论问题是什么,由于我的调用adminAddUserToGroup似乎完全没有响应,所以我无法诊断它。


啊,我明白了。我使用稍微修改过的代码成功地使它工作了。我将Lambda函数设置为由“Post Verification”触发,它能够成功地将用户添加到适当的组中。现在我正在尝试找到一种方法,通过Cognito用户自定义属性传递适当的组名,以便我不需要在函数中硬编码它。我想对于我的最初的问题,我被AWS论坛和其他地方的各种帖子所困惑,但正如你所提到的那样,它已经按原样工作了。谢谢。 - Anjan Biswas
你为什么想要将组名存储在自定义属性上?如果你只是想避免硬编码组名,那么可以使用环境变量。这应该非常简单设置,特别是如果你正在使用无服务器框架或类似的东西。 - 0x6C38
我們的應用程序中有三種不同類型的使用者可以註冊,對應有三個組。使用者(或組)的類型是通過使用者在應用程序中註冊的方式來確定的。根據使用者的類型,在用戶從應用程序中進行註冊時,我將為新用戶分配自定義屬性,然後最終在Lambda函數中使用該屬性來推斷組名稱。環境變量是可以的,但我仍然需要一種方法告知我的Lambda函數哪個用戶屬於哪個組。不確定是否有其他更好的方法。 - Anjan Biswas
我曾经认为用户可以编辑自己的自定义属性(尽管不要引用我说的话)。我能想到的唯一其他选择是为每种类型的用户设置单独的用户池。 - 0x6C38
一些默认的自定义属性肯定可以由用户添加,但是我在创建用户池时添加了自己的自定义属性,比如“user_permission”。然后,在调用SignUp()方法时,我将user_permission的值与其他参数一起传递到参数对象中。有关如何传递自定义属性的更多信息,请参见此链接 - https://aws.amazon.com/blogs/mobile/aws-amplify-adds-support-for-custom-attributes-in-amazon-cognito-user-pools/ - Anjan Biswas
显示剩余4条评论
2个回答

8
主要问题在于你将函数定义为异步函数。 如果你定义了异步函数,就不应该在函数体中使用回调函数。 请确保在函数体中使用 Promise 版本。
try {
    await cognitoISP.adminAddUserToGroup(params).promise();
} catch (error) {
    console.error(error);
}

像这样


将函数从异步改为普通的,问题就解决了! - 0x6C38

2

除了资源外,一切看起来都很好。

您需要按照以下格式提供Userpool: arn:aws:cognito-idp:REGION:ACCOUNT_ID:userpool/USER_POOL_ID

我正在做同样的事情,但使用资源:*。

检查一下Resource:*是否有效。这样您就能确认问题所在的区域。


将资源更改为“*”似乎没有任何效果。无论成功或失败,云监控仍然没有日志。 - 0x6C38

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接