Cognito User Pools is an AWS service that provides applications with user identity and auth. This series of articles cover a full stack solution that enables users to sign in with their Email + Password, Google Sign In, or SSO (SAML), and link all methods to the same user within the app:
This article focuses on using CDK to create our Cognito User Pool resources as Infrastructure as Code (IAC). If youâre already familiar with this you should consider moving onto the next part of this series Sign in with Email, Google, or SAML and link to a single user, since IAC can be a little lengthy (and boring).
Cognito User Pool CDK (IAC)
Letâs start with the basic setup of the Auth construct before we dive into the details defined in the class methods:
User Pool
User Pool Client
We specify up to 2 OAuth callback URLs:
http://localhost:3001/ for local development. Consider removing this for production.
webAppUrl The live web app URL. In Code Genie, this is passed in as either the web appâs custom domain name (if one is defined in cdk.json for the environment weâre deploying) or the default Amplify Hosting URL.
Identity Providers
Define the scopes and attributes from the External IDP that we want to store against our User in our User Pool. Weâre grabbing the profilePicture so that we can display the userâs profile picture against their name.
Thereâs a circular dependency between the Cognito User Pool and the SAML App you create in Google Workspace. Exit early if no GoogleIDPMetadata.xml file exists. When you create the SAML App, youâll need to provide the UserPoolRedirectUrlACS and UserPoolEntityId values from cdk-outputs.development.json. Download the SAML Appâs metadata file and redeploy your CDK Stack.
We must hardcode the SAML Identity Provider name (GOOGLE_SAML_IDENTITY_PROVIDER_NAME) to prevent a second circular dependency between the SAML Identity Provider and the PreSignup Cognito Trigger (which weâll meet soon). It doesnât seem like this should be a circular dependency since both resources are attached to the User Pool and the SAML Identity Provider has nothing to do with Triggers, but CDK will give you a âCircular dependency between resourcesâ nonetheless.
Our attribute mappings for the SAML Identity Provider are similar to the Google Identity Provider. Unfortunately we donât have access to a profile picture, and even though weâre requesting fullname here, Google doesnât allow you to map it when creating the SAML App. Weâll handle this later.
Triggers
Setting AUTO_VERIFY_USERS in development and testing environments is really convenient. Itâs just as convenient in production, but there are good reasons to require email confirmation (such as GDPR compliance).
We add our GOOGLE_SAML_IDENTITY_PROVIDER_NAME environment variable since weâll need that in the Lambda Functionâs code.
Our Lambda Function requires 5 permissions for the User Pool. Unfortunately we canât specify this.userPool.userPoolArn as the resource since CDK once again complains about a circular dependency. Weâre left with granting access to all User Pools within the same account and region.
Environment Config
The cdk.json looks like this:
StringMap
Create External Identity Providers
Google Sign-in
Login to Google Cloud Console and select or create the relevant project.
Select âWeb applicationâ as the âApplication typeâ and enter a name
Click âAdd URIâ under âAuthorised JavaScript originsâ. Copy the value for UserPoolRedirectUrlACS from cdk-outputs.dev.json and paste in only the domain part (i.e remove the â/saml2/idpresponseâ).
Click âAdd URIâ under âAuthorised redirect URIsâ. Copy the same value from above, but this time add â/oauth2/idpresponseâ to the end.
Click âAdd appâ => âAdd custom SAML Appâ. Enter a name for your app.
Download the metadata file to ./packages/cdk and click Continue.
From cdk-outputs.development.json, copy the values for UserPoolRedirectUrlACS and UserPoolEntityId and paste them into the respective fields in the Service Provider Details form and click Continue.
Add attribute mappings: Primary email => email; First name => first_name; Last name => family_name. Click Finish.
Click the User Access card; select âON for everyoneâ and click Save.
Run npm run deploy:dev
End
Now that weâve created our AWS Cognito User Pool and both External (Sign in with Google) and Internal (SAML) Google Apps, weâre ready to move onto more interesting topics: Sign in with Email, Google, or SAML and link to a single user. This next article focuses on the Lambda Handler logic of the Lambda Functions we created with CDK.