User Authentication and Authorization with AWS Cognito

AWS Cognito is a server-less authentication service for web applications that can be leveraged to handle user data and authentication flows within any database or server. It provides administrators with the ability to configure their own identity (authentication) provider and have control over management features such as user sign up, sign in and password management.

Imagine a scenario where a web application needs to access AWS resources using AWS SDK with authenticated users. The simplest way of doing this would be to include a secret key of a AWS user to enable access to AWS resources, but this method is less secure and doesn’t allow access to be restricted to certain users. This is where where user authentication comes in to play either with AWS Cognito or with external authentication providers.

To allow AWS resources access to users with authentication providers in Cognito, “Identity Pools” are used. Identity Pools provide AWS access via federated authentication - authentication via multiple external authentication providers such as Facebook, Amazon, Google, OpenID connect providers and SAML Identity providers.

In addition to Identify Pools, AWS Cognito also requires a token - received from either an external authentication provider, or the AWS Cognito authentication provider itself - in order to successfully authenticate a user. Using an external provider is the least troublesome option because the provider is responsible for handling the user sign up, sign in and password management. (Read this blog, which explains how to use a Google authentication provider with AWS Identity Pools.)

This blog post will provide a detailed walk-through on configuring an application to access AWS resources using AWS SDK with authenticated users by configuring an identity pool with an identity provider, and creating a simple static HTML web app for user sign up and sign in. After authentication, the app will list the objects of a specified S3 bucket to showcase the authorized access the logged in user has received.

Below is a video demonstrating the demo web app that will be built in this blog. It consists of user registration, user verification, user login and an authenticated query request to an S3 bucket - All using our own AWS Cognito authentication provider with no 3rd party involvement. Everything is in our control.

AWS Cognito Demo




Prerequisites

An AWS account with some basic knowledge of working with AWS services - the following AWS services will be utilized throughout this guide:

  • AWS Cognito Service
  • Simple Storage Service
  • Identify Access Management Service

You will learn

  • How to configure an AWS Cognito authentication provider according to your needs
  • How to host a static web app in an AWS S3 bucket
  • How to register, verify and login an user using AWS Cognito Javascript SDK
  • How to use AWS Cognito Identity JavaScript SDK to get temporary access credentials
  • How to use AWS S3 JavaScript SDK to query S3 bucket items using temporary access credentials

High Level Architecture

In order to understand how all of this works, take a look at the high level architecture below, which showcases the components and services involved, and the jobs they perform.




The main steps of this process are as follows;

1.User registration
• User enters their email address, user name and password and registers with the User Pool

2.User verification
• The Cognito User Pool will a verification code via email or SMS, and the user enters the code to verify themselves with the User Pool

3.User log-in
• The user enters their user name and password, and logs in to the Cognito User Pool in which case a token will be provided by Cognito upon successful login

4.Get temporary credentials
• The Cognito Identity Pool will provide temporary credentials to AWS resources using the token that was received on successful login

5.User authorization
• Cognito will authorize the user with the necessary permissions with IAM role

6.AWS resource management
• The authorized user will now have the ability to manage AWS resources according to the permissions provided by the AWS IAM.

Let’s now get started on configuring the application…

Step 1: Configuring a User Pool

The User Pool provides features to control user sign up, sign in and user management with more advanced features. Follow the steps below to create a user pool:

1.Go to the AWS Cognito service and click “Manage User Pools”.

2.Click “Create a user pool”, provide a “Pool name” and click “Review defaults” as below.




3.The next page will display the default settings. It is possible to customize features such as user attributes, password policies, verification by email or phone and multi-factor authentication settings. To keep things simple, this guide will keep the default settings. Click “Create pool”.

4.Copy the generated “Pool Id” from “General settings” section as below.




5.Go to the “App Clients” section and click “Add an app client”.

6.Give an “App client name” and uncheck “Generate client secret” as below. The reason for this is, to quote from AWS document, “when creating the App, the ‘generate client secret’ box must be unchecked because the JavaScript SDK doesn’t support apps that have a client secret.” — AWS Document. Click “Create app client”.




7.Copy the generated “App client id” from “App clients” section as below.




Step 2: Configuring an Identity Pool

The Identity Pool gives AWS resource access after it verifies that the token provided is a valid token generated by a registered authentication provider. In this case, the authentication provider that will be registered with the Identity Pool will be the AWS Cognito authentication provider that was created in step 1.

2.1. Creating an Identity Pool

1.Go to the AWS Cognito service and click “Manage Identity Pools”.

2. Enter “Identity pool name”, expand the “Authentication providers” section and select the “Cognito” tab. This is where the Cognito authentication provider will be registered with the Identity Pool.

3.Paste the “Pool Id” copied in step 1.4 in the “User Pool ID” field, and paste the “App client id” copied in step 1.7 in the “App client id” field.




4.In the “Your Cognito identities require access to your resources” page, take note of the IAM Roles that will be created for authenticated and unauthenticated users as displayed below. Necessary IAM Role Policy will need to be given to these roles. In this example, the authenticated user role which is “Cognito_MSNIdentityPoolAuth_Role” will be given full AWS S3 access. This will be done in the next step. Click “Allow” to finish creating Identity Pool.




5.After creation go to the created Identity Pool dashboard and click “Edit Identity Pool” and copy the “Identity pool ID” as displayed below.




2.2. Allow AWS Resource Access to Identity Pool Role

1.Go to AWS IAM Service -> Roles and find the role that was noted in step 2.1.4. and click “Attach policies”.

2.Search and add “AmazonS3FullAccess” as below and click “Attach policy”. Now any authenticated user that will assume this role will have access to work with AWS S3.




Step 3: Creating an S3 Bucket for Web Hosting

1.Go to AWS S3 page and click “Create bucket”

2.Enter a “Bucket name” and click “Next”

3.In the “Set permissions” section, set the permissions as below:




4.Click on the created bucket and go to bucket properties.

5.Enable the “Static website hosting” and configure as below. Enter “Index document” as “index.html”. Copy the “Endpoint” URL - the web app that will be hosted is accessed using this endpoint.




6. Click on “Permissions” tab and go to “CORS configuration” and paste the below XML code and click “Save”. This will allow cross origin access.




Step 4: Creating and Hosting The Web App




Key points in the code are,

Line 168
Gets the ID token after a user is successfully logged in with AWS Cognito authentication provider.

Line 335
Gets the ID token from an already logged in user session. This method is called on the page load.

Line 272
Gets the temporary credentials for AWS services using ID token, Identity Pool ID and User Pool ID and updates the AWS credentials.

2. Open “index.html” and replace following place holder values and save.

<User Pool ID> with the value copied in step “1.4”.

<App Client ID> with the value copied in step “1.7”.

<Region> with the region code of the region that you have created your services. You can get region codes from here.

<Identity Pool ID> with the value copied in step “2.1.5”.

3. Go the S3 bucket that was created in step “3” and drag the “index.html” as well as “script” directory as below and click “Upload”.




4.In order to allow public access, Select all the files, click on “Actions” and select “Make public” as below.




5.Go to the endpoint that was copied in step 3.5 and you will be presented with the login page. Go ahead and try out create, verify and login a user, and provide the bucket name that was created in step 3 for the S3 bucket name and it will successfully display the files that were uploaded. By default, a verification code will be sent to your email.

Congrats! Now you now how to utilize AWS Cognito into your app and unleash the full power of it!

Suminda De Silva

Senior Software Engineer