Authentication and Federate Identity management using AWS Cognito and SAML
Authorizing and managing access to users is an important part of web or app development. Your application/website needs to have a feature to auto-enroll new users automatically at the same time managing the security of the data.
AWS Cognito comes with all these features inbuilt in it where you can use the OAuth 2.0 authentication protocol to manage your user pool.
Let’s start with a brief introduction to the OAuth2.0 authentication protocol. OAuth 2.0 is an open-standard authentication protocol that is used to enable Single sign-on to different applications using federated logins. If you remember multiple websites where you log in using your Gmail or Facebook or Twitter account, this is an example of using the OAuth single-sign-on feature to log in to a system without creating an account.
AWS Cognito comes with a bearer and refresh token mechanism where you can use either AWS provided user pools or third party accounts via SAML based credential management. Let’s look into details of how AWS Cognito works.
This article is divided into 3 major steps to be taken by developer:
Step 1. Get the SAML xml file
For our implementation, we used Microsoft Azure AD as Identity Provider. There are other options too which can be explored, but in this article, we will target Azure AD as IdP.
Azure AD uses a certificate to sign the SAML tokens it sends to the application. You need this certificate to configure the trust between Azure AD and the application. To understand the complete working of Azure AD, please go through the Azure documentation here. On a high level the major components needed to create a SAML file are:
- Reply URL: The application URL which will receive the SAML token
- SAML metadata file: An XML file which will be generated once the details are configured successfully on the Azure AD application
Note: We had a separate team that took care of the Azure AD metadata file part.
Step 2. Configure the AWS Cognito
AWS Cognito comes with all the required pieces in terms of the authorization. Navigate to Cognito service on your AWS account and create a new user pool for your application.
Configure the Identity provider setup from the option. Upload the SAML metadata XML here and save.
Provide the redirection URL in the callback URL section. The application will be redirected to this URL on successful authentication. Also, provide a valid logout URL in case of user clicks on logout.
You can make use of AWS Cognito hosted UI as your login screen, or create a custom login screen. We have used AWS hosted UI to help users log in to the application. The UI is completely customizable according to your needs using the HTML and CSS files. We won’t get into details of that in this article.
Create users in the “Users and groups” screen which will be using the applications. You can create user groups and control the access to the user from the user group.
Step 3. Handle authorization on the API calls
There are two ways this can be achieved, if you are making use of AWS API Gateway, you can directly add an authorization layer on the API call, which will by default check the auth token validity and allow only suitable users.
The other way is completely custom. For those who have not configured API gateway from AWS and have API endpoints hosted directly on EC2 IP ports. In this case, we need to make use of AWS IdP SDK calls and authorize every API calls. Every API request which needs to be authorized needs to be modified and an additional authorization token needs to be sent along with the request from the frontend application to the backend system.
Whenever receiving the request, the backend needs to do the token validity check and throw an error if not authorized. AWS SDK comes in very handy in all AWS Cognito functions. All the functions related to Cognito are provided in AWS documentation here.
The below code gives an idea of how the AWS SDK can be used to generate the bearer token whenever a user is trying to log in and make use of this token on every subsequent API calls
Below snippet of code that gives us an idea of how to validate the token provided from the frontend.
The TTL (Time To Live) of the access token is configurable from the Cognito portal. There are two types of token validity which are of interest here, “Access token expiration” and “Refresh token expiration”. As the name suggests, these values define the duration after which the new token is required. The below code explains how a new token can be generated once it is expired.
If the requirement is just to log in using SSO, these functions need small modifications. When an SSO request is triggered from the frontend, Cognito automatically redirects the user to the screen where SSO credentials are to be filled up. On the success of the authorization process, the user is redirected to the “Callback URL” which was configured while setting up the Cognito user pool on AWS console. On the redirection, an access token is generated automatically for the user pool and is appended to the redirection URL. The frontend code needs to fetch the access token and trigger a validation API call to the backend. The token validation can be achieved using below code snippet.
Once the success response is received from the backend for this API call, the user will be successfully navigated to the actual landing screen of the application.
Using AWS Cognito helps us to streamline the complete authentication and authorization piece very easily as all the hard work is done on the AWS level. The token generation, encryption, validation, etc. Cognito hosted UI also has many default functions like Sign-Up, Forget password, and reset the password.
I hope this article was helpful for users to implement the complete Cognito solution.