Cognito Construct Library
nija-at opened this issue · comments
PR | Champion |
---|---|
#91 | @eladb |
Description
Increase coverage of CDK construct library for Cognito to cover a lot more features than it currently does. Where necessary, re-design the APIs so they are more ergonomic and extendible.
Progress
- Tracking Issue Created
- RFC PR Created
- Core Team Member Assigned
- Initial Approval / Final Comment Period
- Ready For Implementation
- implement User Pool construct
- implement UserPoolUser and UserPoolGroup constructs
- implement IdentityPool & IdentityPoolRoleAttachment constructs
- open issues to track unimplemented features
- Resolved
Curious if there is a current ETA on these features landing/if they are actively being worked on at the moment?
Some of these have started landing - https://github.com/aws/aws-cdk/commits/master/packages/%40aws-cdk/aws-cognito/lib, however, we don't have an ETA.
Is there a particular feature you're looking for?
I'm basically looking to setup a new cognito auth stack, custom domain, some federated logins, attach some custom lambda hooks, etc.
I saw the cognito construct features that landed very recently, but haven't incorporated those yet. So far i've been working around with everything else as required at the Cfn*
CloudFormation level + using escape hatches.
Another issue I have just run into (though it's a CloudFormation deficiency, so beyond the scope of CDK, unless you were to roll a custom resource to resolve it) is that it's not currently possible to retrieve the CloudFront target when setting a custom domain, as per aws-cloudformation/cloudformation-coverage-roadmap#356 (Edit: added an example custom resource workaround in my comment)
Also, tangentially related, it would be nice if we could construct a CloudFrontTarget from a string of the distribution's domain name:
A very quick and dirty hacky workaround example:
class CloudFrontFromStringTarget {
constructor(distributionDomainName) {
this.distributionDomainName = distributionDomainName
}
bind(_record) {
return {
// CloudFront Zone ID
hostedZoneId: 'Z2FDTNDATAQYW2',
dnsName: this.distributionDomainName
}
}
}
For reference, I'll include some code snippets from my project that cover some of the things i needed that aren't yet supported here.
Example: Using a custom domain name with UserPool
const cdk = require('@aws-cdk/core')
const cognito = require('@aws-cdk/aws-cognito')
const cr = require('@aws-cdk/custom-resources')
const route53 = require('@aws-cdk/aws-route53')
/**
* Configures the UserPool domain used for authentication.
*
* @see https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-cognito.CfnUserPoolDomain.html
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpooldomain.html
* @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-assign-domain.html
*/
const userPoolDomain = new cognito.CfnUserPoolDomain(
this,
'UserPoolDomain',
{
userPoolId: userPool.userPoolId,
domain: authDomain,
customDomainConfig: {
certificateArn,
},
}
)
userPoolDomain.node.addDependency(userPool)
new cdk.CfnOutput(this, 'UserPoolDomainValue', {
value: userPoolDomain.domain,
})
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#describeUserPoolDomain-property
const describeCognitoUserPoolDomain = new cr.AwsCustomResource(
this,
'DescribeCognitoUserPoolDomain',
{
resourceType: 'Custom::DescribeCognitoUserPoolDomain',
onCreate: {
region: 'us-east-1',
service: 'CognitoIdentityServiceProvider',
action: 'describeUserPoolDomain',
parameters: {
Domain: userPoolDomain.domain,
},
physicalResourceId: cr.PhysicalResourceId.of(userPoolDomain.domain),
},
// TODO: can we restrict this policy more? Get the ARN for the user pool domain? Or the user pool maybe?
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
}),
}
)
describeCognitoUserPoolDomain.node.addDependency(userPoolDomain)
const userPoolDomainDistribution = describeCognitoUserPoolDomain.getResponseField(
'DomainDescription.CloudFrontDistribution'
)
new cdk.CfnOutput(this, 'UserPoolDomainDistribution', {
value: userPoolDomainDistribution,
})
// Route53 alias record for the UserPoolDomain CloudFront distribution
new route53.ARecord(this, 'UserPoolDomainAliasRecord', {
recordName: userPoolDomain.domain,
target: route53.RecordTarget.fromAlias({
bind: _record => ({
hostedZoneId: 'Z2FDTNDATAQYW2', // CloudFront Zone ID
dnsName: userPoolDomainDistribution,
}),
}),
zone,
})
Example: Getting the UserPoolClient secret
Ref: aws/aws-cdk#3037 (comment)
const describeCognitoUserPoolClient = new cr.AwsCustomResource(
this,
'DescribeCognitoUserPoolClient',
{
resourceType: 'Custom::DescribeCognitoUserPoolClient',
onCreate: {
region: 'us-east-1',
service: 'CognitoIdentityServiceProvider',
action: 'describeUserPoolClient',
parameters: {
UserPoolId: userPool.userPoolId,
ClientId: userPoolClient.userPoolClientId,
},
physicalResourceId: cr.PhysicalResourceId.of(userPoolClient.userPoolClientId),
},
// TODO: can we restrict this policy more?
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
}),
}
)
const userPoolClientSecret = describeCognitoUserPoolClient.getResponseField(
'UserPoolClient.ClientSecret'
)
new cdk.CfnOutput(this, 'UserPoolClientSecret', {
value: userPoolClientSecret,
})
Apologies, but I have removed this comment. Please file a separate bug for issues you are facing. (see aws/aws-cdk#6811) Thanks!
-- @nija-at
Please continue tracking progress on Cognito here - aws/aws-cdk#6765
Resolving this issue.