AWS Cognito/Amplify - have new user sign ups be automatically add to a user group

11,285

Solution 1

I got it working. As mentioned by Vladamir in the comments this needs to be done server side, in a Post Confirmation lambda trigger. Here is the lambda function.

'use strict';
var AWS = require('aws-sdk');
module.exports.addUserToGroup = (event, context, callback) => {
  // console.log("howdy!",event);
  var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
  var params = {
    GroupName: 'users', //The name of the group in you cognito user pool that you want to add the user to
    UserPoolId: event.userPoolId, 
    Username: event.userName 
  };
  //some minimal checks to make sure the user was properly confirmed
  if(! (event.request.userAttributes["cognito:user_status"]==="CONFIRMED" && event.request.userAttributes.email_verified==="true") )
    callback("User was not properly confirmed and/or email not verified")
  cognitoidentityserviceprovider.adminAddUserToGroup(params, function(err, data) {
    if (err) {
      callback(err) // an error occurred
    }
    callback(null, event);           // successful response
  });  
};

You will also have to set the policy for the lambda function role. In the IAM console, find the role for this lambda and added this inline policy. This give the lambda the keys to the castle for everything cognito so make yours more restrictive.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cognito-identity:*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cognito-sync:*"
            ],
            "Resource": "*"
        },
        { //this might be the only one you really need
            "Effect": "Allow",
            "Action": [
                "cognito-idp:*"
            ],
            "Resource": "*"
        }
    ]
}

Solution 2

Cognito won't know which group a newly signed-up user needs to be a part of. You have to programmatically (or manually) assign the user to a specific group. Once your code places the user into a specific group, the JWT ID token will contain a list of all of the relevant groups/IAM roles that this users is a part of.

More info on groups here.

Solution 3

AWS Amplify has added support for adding users to groups using amplify cli. Details are given here https://aws.amazon.com/blogs/mobile/amplify-framework-adds-supports-for-aws-lambda-triggers-in-auth-and-storage-categories/

Also this article explains bit more details https://medium.com/@dantasfiles/multi-tenant-aws-amplify-method-2-cognito-groups-38b40ace2e9e

Passing group name from client side to you lamda function you can use Post Confirmation Lambda Trigger Parameter clientMetadata object like below.

  await Auth.signUp({
          username: this.email,
          password: this.password,
          attributes: {
            given_name: this.firstname,
            family_name: this.lastname
          },
          clientMetadata: {
            key: value
          }
        })

If you are using ready made amplify auth UI then you need to customize withAuthenticator component and write your own component for signup or preferrable ConfirmSignUp (plz check if you can pass clientMetadata from there)

Within lamda function you can get passed group name like this

event.request.clientMetadata.groupName
Share:
11,285
honkskillet
Author by

honkskillet

Updated on June 09, 2022

Comments

  • honkskillet
    honkskillet almost 2 years

    I am using AWS Amplify library to sign up and perform Auth for an AppSync project. This uses Cognito. However, when a new user signs up via Amplify/Cognito, the new user isn't assigned to any specific group in the cognito pool. I am using the Amplify higher order component for login/signup.

    import { withAuthenticator } from 'aws-amplify-react';
    

    which I wrap over a component

    class Authenticator extends React.Component {
       //... basically empty component, only exists so I can wrap it w/ the HOC
    }
    export default withAuthenticator(Authenticator)
    

    Amplify is set up in index.js

    import config from './aws-exports';
    import Amplify from 'aws-amplify';
    Amplify.configure(config);
    

    aws-exports.js was autogenerated by AWS Mobile Hub CLI. Looks like...

    const awsmobile = {
        'aws_app_analytics': 'enable',
        'aws_cognito_identity_pool_id': 'us-west-2:XXX',
        'aws_cognito_region': 'us-west-2',
        'aws_content_delivery': 'enable',
        'aws_content_delivery_bucket': 'flashcards-hosting-mobilehub-XXX',
        'aws_content_delivery_bucket_region': 'us-west-2',
        'aws_content_delivery_cloudfront': 'enable',
        'aws_content_delivery_cloudfront_domain': 'XXX.cloudfront.net',
        'aws_mandatory_sign_in': 'enable',
        'aws_mobile_analytics_app_id': 'XXX',
        'aws_mobile_analytics_app_region': 'us-east-1',
        'aws_project_id': 'XXX',
        'aws_project_name': 'flash-cards',
        'aws_project_region': 'us-west-2',
        'aws_resource_name_prefix': 'flashcards-mobilehub-XXX',
        'aws_sign_in_enabled': 'enable',
        'aws_user_pools': 'enable',
        'aws_user_pools_id': 'us-west-2_XXX',
        'aws_user_pools_mfa_type': 'OFF',
        'aws_user_pools_web_client_id': 'XXX',
    }
    export default awsmobile;
    
  • Vladimir
    Vladimir about 6 years
    btw, you can use a Post confirmation Lambda hook to "automatically" add the user to a Cognito group, but you'll need to write the code and make sure you understand what the logic is behind which users go into which group.
  • honkskillet
    honkskillet about 6 years
    How do you programmatically set the group?
  • honkskillet
    honkskillet about 6 years
    I don't see how to do it is the Amplify Auth docs aws.github.io/aws-amplify/api/classes/authclass.html
  • Ionut Trestian
    Ionut Trestian about 6 years
    This isn't something you can achieve via Amplify. As Vladimir mentioned you can configure a Post Confirmation lambda trigger for your user pool and call the ListGroups and AdminAddUserToGroup Cognito UserPool APIs to achieve that docs.aws.amazon.com/cognito/latest/developerguide/…
  • honkskillet
    honkskillet about 6 years
    Got it. I'll try to hook it up tomorrow.
  • honkskillet
    honkskillet about 6 years
    Started on this by adding a Post Confirmation trigger lambda function. Currently, no matter what I do inside the lambda I get the error "Unrecognizable lambda output", which is strange because I don't think cognito is expecting any response. What should my lambda function return?
  • Vladimir
    Vladimir about 6 years
    Here's a bunch of samples for you: docs.aws.amazon.com/cognito/latest/developerguide/…
  • Vladimir
    Vladimir about 6 years
    Great. Accept my answer when you have a chance then ;)
  • Ahmet Cetin
    Ahmet Cetin over 5 years
    Hi, how do you point to that lambda function? In Federated Identities, under Facebook, Cognito Events -> Sync Trigger? I did this, but the lambda function never triggered.
  • tobiv
    tobiv over 5 years
    Thank you for sharing! Have not added federated yet, but for user pools it is in fact as easy as adding the lambda function, selecting it in cognito triggers, adding the role policy (the statement you commented was enough). Signed up a new user, boom – working.