12

我正在尝试使用 CognitoUserPool 作为一个身份验证提供程序创建一个 Cognito FederatedIdentityPool。创建 UserPool 很简单:

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

但是我不确定如何将其连接到身份池:

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

根据IdentityProvider API Documentation,它看起来有一个属性cognitoIdentityProviders,但是它接受一个cdk.Token/CognitoIdentityProviderProperty.

现在我尝试创建一个CognitoIdentityProviderProperty对象并传递它cognitoIdentityProviders: [{ clientId: userPoolClient.userPoolClientId }],但我得到以下异常:

 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

我什至尝试从 AWS 控制台复制 id 并在此处对其进行硬编码,仍然是同样的错误。

  1. 有人可以帮我解释如何在CfnIdentityPool.
  2. 为什么会有UserPoolCfnUserPool?它们之间有什么区别,应该使用哪一个?
4

3 回答 3

34

当您使用用户池作为身份提供者创建身份池时,这是我设法模仿通过 aws 控制台创建的默认配置的方式。除了您所要求的之外,它还包括一些其他功能(允许未经身份验证的访问并指定密码策略),但很容易根据您的需要进行修改。

    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
        }
    });

为什么会有 UserPool 和 CfnUserPool?它们之间有什么区别,应该使用哪一个?

UserPool 是资源的高级表示,是首选的工作方式,但尚未实现所有属性。CfnUserPool(任何 Cfn 前缀类)是映射到 Cloudformation 资源的低级表示。当高级课程不能满足您的需求时,您可以使用两者,如示例中所示。

于 2019-07-23T17:03:52.230 回答
3

我能够弄清楚我们如何将 UserPool 附加到身份池

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

    const identityPool = new cognito.CfnIdentityPool(this, 'MyCognitoIdentityPool', {
      allowUnauthenticatedIdentities: false,
      cognitoIdentityProviders: [{
        clientId: userPoolClient.userPoolClientId,
        providerName: userPool.userPoolProviderName
      }]
    });

仍在努力将角色附加到 IdentityPool 并且不知道 CfnUserPool 和 UserPool 之间的区别。但是,这个问题可以标记为部分解决。

于 2019-04-21T21:00:57.817 回答
2

CDK 必须已更改此创建。我使用来自@CCarlos 的示例得到了它:

const pool = new cognito.CfnUserPool(this, "cdkUserpool", {
  userPoolName: "cdkUserPoolName",
  usernameAttributes: ["email"],
});
const client = new cognito.CfnUserPoolClient(this, "cdkClient", {
  userPoolId: pool.ref, // <--- This part has changed.
  explicitAuthFlows: ["ADMIN_NO_SRP_AUTH"],
  generateSecret: false,
  readAttributes: [
    "preferred_username",
    "website",
    "email",
    "name",
    "zoneinfo",
    "phone_number",
    "phone_number_verified",
    "email_verified",
  ],
  writeAttributes: ["name", "zoneinfo", "phone_number"],
});
于 2020-10-18T11:58:11.700 回答