AWS

Cognito Authentication on AWS

By 03/06/2019 March 12th, 2019 No Comments

Few Words of Introduction

Authentication is required for most  applications and it is a usual step in any development process. The implementation of security mechanisms is quite difficult and painful to do with one’s own hands. A much better idea than spending a lot of time building your own authorization is to  get a ready-made solution… so why not try AWS Cognito? Can we do it without any source code lines?

Implementation of the Cognito is not very complicated while the security is provided by AWS security team and it therefore should be safe. Especially when we want to authenticate a simple application or share AWS services, for example S3 bucket or API Gateway services.

The initial  requirement is to have an AWS account. Then we need to prepare two Cognito objects such as User Pool and Federated Identities and simple API Gateway endpoint for tests.

Authentication flow, in the following case, for communication between the client, the authentication mechanism and the  services are presented by the below diagram:

 

We going to try and open the login page using predefined Cognito forms, obtain an AWS STS token, redirect user to API Gateway to execute Lambda function if the obtained AWS STS token is correct. 

Let’s get Started…

To create a User Pool we have to go to AWS Console – > Cognito services and Create a User Pool:

By going to Step through settings we have to decide how are the users going to be authenticated. In this case it is done by using the email:

The next step is to decide how strong requirements for passwords are we setting up:

The following step is one of the most important Cognito authentication futures: Multi Factor Authentication without any additional development as well as user verification using email or phone:

If necessary, we can customize messages sent to users as well… just brilliant 😊

It is possible to add tags to User Pool but  this time we shall skip this step.
We can register users’ devices without any additional steps and customizations:

To provide authentication and recognition between different apps connected to our new User Pool we need to create App Client definition, simply by  using Add an app client link:

This time we don’t need client secret, so I unchecked it from defaults. Have a look how important the  futures on this form are.

If the standard authentication flow doesn’t not fit for our requirements we can use Lambda functions to customize every step of this process. The customization process is made by Triggers on every main step in the standard Authflow.

We have now created User Pool:

To make our example more user friendly for testing we can provide Domain Name for our User Pool and company Logo for Login form generated by Cognito:

To play with API and other Identity Providers like Google, Facebook and others I suggest using enabled OAuth 2.0 and allowing urls of resources to test, in this example we’re using the url of test API.

Identity Pool

To authenticate users we need to create an Identity Pool assigned to the newly created User Pool. Identity Pool is important because there we can assign user roles and permissions to users which are authenticated and not authenticated. To do this we have to go to Federated Identities and create one:

Adding predefined roles by selecting Allow button:

To make the  admin process friendlier, AWS prepared simple user and group management as well as role assignment to the group – in most projects it is enough. We can also import users from CSV file which might be important for more than few users.

To do so we have to go to User Pools -> General settings –> User and groups and we can create a user:

Please, notice that  what is important is the user status, i.e. FORCE_CHANGE_PASSWORD.

API Preparation for Tests

To test the API we have to create Cognito authorizer on API Gateway, Lambda and API Gateway endpoint for it and we should choose Cognito authorization method:

 

It is important  to notice the name of the Token Source as it is required in header for requests to API.

And we should change the Authorization on the requested API method:

Testing

Finally we can and see if everything works. How do we test it? Let’s try Cognito endpoint and its methods documented on:

https://docs.aws.amazon.com/cognito/latest/developerguide/login-endpoint.html

First, we have to invoke login url for our newly created Cognito Client and we then try to redirect it to our API Gateway or S3 bucket or other location. For security reasons Cognito does not allow every url for redirection, therefor we have to define it in App Client Settings.

 

The url should have the following format:

https://<COGNITO_DOMAIN>.auth.eu-west-1.amazoncognito.com/login?response_type=code&client_id=<COGNITO_CLIENTID>&state=STATE&scope=profile&redirect_uri=https://<API_ENDPOINT>.execute-api.eu-west-1.amazonaws.com/dev/<API-GATEWAY>

And there it is – when everything is done correctly we should have login page displayed with our custom logo.

What is important, as well as difficult and boring, is the implementation of new applications : changing the password, signing up a new user, renewing  the password, session expiration and other flows not implemented in all applications. All these flows are implemented by specialists from AWS in Cognito. After the first login we are redirected to change the password form.

After changing the password and logging in the Cognito redirects us to the endpoint written to the redirect_uri parameters. We get the message “Missing Authentication Token” – why? We do not have the possibility to send the required IdToken  directly from web browser. Everything works fine.

We can now test the solution  by executing our Gateway API using for example Postman. We have to pass  IdToken to the header as the Authorization parameter.

Now  we have our API secured by Cognito. When we log out and log in again we can execute our API.

Disclaimer

Bear in mind that this article does not aim to build a fully secure authorization, this is only a sandbox to start with Cognito and get some basic knowledge about the Authentication process. Every security implementation should be carefully configured and fully tested because every small misconfiguration could have a dramatic impact on the  application and AWS account security.

So, what did we Achieve?

We have secured our applications, API’s and other resources which is very important. Cognito can help us to achieve this process without any coding, not in all projects, but most of them. Another benefit is that if we have correctly implemented this process we can be secured from development mistakes because the Cognito service has been tested and widely used by AWS specialists and other clients.