Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create Cognito IdentityPool with Cognito UserPool as one of the Authentication provider using aws cdk?

I am trying to create a Cognito FederatedIdentityPool with CognitoUserPool as one Authentication Provider. Creating UserPool was easy enough:

    const userPool = new cognito.CfnUserPool(this, 'MyCognitoUserPool')
    const userPoolClient = new cognito.CfnUserPoolClient(this, 'RandomQuoteUserPoolClient', {
      generateSecret: false,
      userPoolId: userPool.userPoolId
    });

However I am not sure how to connect this to an Identity Pool:

    const identityPool = new cognito.CfnIdentityPool(this, 'MyIdentityPool', {
      allowUnauthenticatedIdentities: false,
      cognitoIdentityProviders: ?????
    });

Based on IdentityProvider API Documentation it looks like there is a propert cognitoIdentityProviders, however it accepts an array of cdk.Token/CognitoIdentityProviderProperty.

Now I tried creating a CognitoIdentityProviderProperty object and pass it cognitoIdentityProviders: [{ clientId: userPoolClient.userPoolClientId }], but I am getting following exception:

 1/2 | 09:48:35 | CREATE_FAILED        | AWS::Cognito::IdentityPool   | RandomQuoteIdentityPool Invalid Cognito Identity Provider (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: InvalidParameterException; Request ID: 4d6d579a-6455-11e9-99a9-85159bc87779)
        new CdkWorkshopStack (/Users/cdk/lib/cdk-workshop-stack.ts:46:26)
        \_ Object.<anonymous> (/Users/cdk/bin/cdk-workshop.ts:7:1)
        \_ Module._compile (module.js:653:30)
        \_ Object.Module._extensions..js (module.js:664:10)
        \_ Module.load (module.js:566:32)
        \_ tryModuleLoad (module.js:506:12)
        \_ Function.Module._load (module.js:498:3)
        \_ Function.Module.runMain (module.js:694:10)
        \_ startup (bootstrap_node.js:204:16)
        \_ bootstrap_node.js:625:3

I even tried copying id from AWS Console and hardcoding it here, still same error.

  1. Can someone please help me in explaining how can I configure Authentication Providers in CfnIdentityPool.
  2. Why is there a UserPool and CfnUserPool? What is difference between them and which one is supposed to be used?
like image 443
c2tarun Avatar asked Apr 21 '19 16:04

c2tarun


People also ask

How do you authenticate with tokens with Cognito?

Authenticating with tokensWhen a user signs into your app, Amazon Cognito verifies the login information. If the login is successful, Amazon Cognito creates a session and returns an ID, access, and refresh token for the authenticated user.

Can AWS Cognito be used for authorization?

Amazon Cognito allows you to use groups to create a collection of users, which is often done to set the permissions for those users. In this post, I show you how to build fine-grained authorization to protect your APIs using Amazon Cognito, API Gateway, and AWS Identity and Access Management (IAM).


1 Answers

This is the way I managed to mimic the default configuration created through the aws console when you create an identity pool with a user pool as identity provider. It includes some other features apart from what you have asked (allows unauthenticated access and specify the password policy), but is easy to modify to your needs.

    const userPool = new cognito.UserPool(this, 'MyUserPool', {
        signInType: SignInType.EMAIL,
        autoVerifiedAttributes: [
            UserPoolAttribute.EMAIL
        ]
    });
    const cfnUserPool = userPool.node.defaultChild as cognito.CfnUserPool;
    cfnUserPool.policies = {
        passwordPolicy: {
            minimumLength: 8,
            requireLowercase: false,
            requireNumbers: false,
            requireUppercase: false,
            requireSymbols: false
        }
    };
    const userPoolClient = new cognito.UserPoolClient(this, 'MyUserPoolClient', {
        generateSecret: false,
        userPool: userPool,
        userPoolClientName: 'MyUserPoolClientName'
    });
    const identityPool = new cognito.CfnIdentityPool(this, 'MyCognitoIdentityPool', {
        allowUnauthenticatedIdentities: false,
        cognitoIdentityProviders: [{
            clientId: userPoolClient.userPoolClientId,
            providerName: userPool.userPoolProviderName,
        }]
    });
    const unauthenticatedRole = new iam.Role(this, 'CognitoDefaultUnauthenticatedRole', {
        assumedBy: new iam.FederatedPrincipal('cognito-identity.amazonaws.com', {
            "StringEquals": { "cognito-identity.amazonaws.com:aud": identityPool.ref },
            "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "unauthenticated" },
        }, "sts:AssumeRoleWithWebIdentity"),
    });
    unauthenticatedRole.addToPolicy(new PolicyStatement({
        effect: Effect.ALLOW,
        actions: [
            "mobileanalytics:PutEvents",
            "cognito-sync:*"
        ],
        resources: ["*"],
    }));
    const authenticatedRole = new iam.Role(this, 'CognitoDefaultAuthenticatedRole', {
        assumedBy: new iam.FederatedPrincipal('cognito-identity.amazonaws.com', {
            "StringEquals": { "cognito-identity.amazonaws.com:aud": identityPool.ref },
            "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "authenticated" },
        }, "sts:AssumeRoleWithWebIdentity"),
    });
    authenticatedRole.addToPolicy(new PolicyStatement({
        effect: Effect.ALLOW,
        actions: [
            "mobileanalytics:PutEvents",
            "cognito-sync:*",
            "cognito-identity:*"
        ],
        resources: ["*"],
    }));
    const defaultPolicy = new cognito.CfnIdentityPoolRoleAttachment(this, 'DefaultValid', {
        identityPoolId: identityPool.ref,
        roles: {
            'unauthenticated': unauthenticatedRole.roleArn,
            'authenticated': authenticatedRole.roleArn
        }
    });

Why is there a UserPool and CfnUserPool? What is difference between them and which one is supposed to be used?

UserPool is a high-level representation of the resource and is the prefered way to work but not all the properties are implemented yet. CfnUserPool (an any Cfn prefixed class) is a low-level representation that maps to a Cloudformation resource. You can use both when the high-level class don't fulfill your necessities, as in the example.

like image 194
soycabanillas Avatar answered Sep 24 '22 08:09

soycabanillas