User authentication through authorization code grant type using AWS Cognito

This article is part of oAuth series using AWS Cognito, see links to other articles in Series Summary: oAuth Made Simple with AWS Cognito.

In previous post – Setting up implicit grant workflow in AWS Cognito, step by step, we show that it takes only …


This content originally appeared on DEV Community and was authored by DEV Community

This article is part of oAuth series using AWS Cognito, see links to other articles in Series Summary: oAuth Made Simple with AWS Cognito.

In previous post - Setting up implicit grant workflow in AWS Cognito, step by step, we show that it takes only 4 simple steps in order to set up implicit grant workflow in AWS Cognito. With that, you can start using AWS Cognito to protect your web server and its resources. However, Implicit Grant is deprecated and no longer recommended. Why?

As you can see from its Testing Time section, the access token issued by AWS Cognito is returned directly back to the client side and used to access other resources on the server side. The same token can be also used to access Cognito Auth APIs and retrieve other user informations. Consequently, it is a highly sensitive piece of information and by allowing client side direct access exposes a significant security risk.

Authorization code grant type is recommended as replacement as a standard practice when it comes to client side authentication for either web or mobile applications. How and why is Authorization Code grant type is better? In the next section, we will deep dive into a typical login workflows through authorization code grant type to find out.

Typical Login Workflows through Authorization Code Grant Type

When we use a web or mobile application, if you exist the app and come back within a short period, you usually have the convenience of access without the need to login again. What goes behind it in order to achieve it? The first workflow we will go through explain exactly how, see its sequence diagram below.

Alt Text

As you can see from the above diagram, once the client load up all the artifacts (as in Step 1, which is only needed for web applications, as mobile app has all client resources as part of its installation bundle), the first thing is to call web server to check its login status, by passing in a session token which it saves locally (either in session storage or cookie for web applications or keychains for iOS app or Shared Preferences for Android app). If the session token is still valid, it will request for the resources for home screen (Step 3), and render home screen without requiring for authentication. However, if the login status check returns false, the session token is removed from the client storage, and the home screen is displayed with login button, allowing users to re-authenticate using the Login workflow as described in the next sequence diagram.

Alt Text

This diagram is the meat of login workflow using Authorization Code grant type. Once the user clicks a login button, the first request the client (either mobile or web application) will make to the server is to request for a login url, which would point to the login page of AWS Cognito. Some application may opt to hard code this in the client side, however, I would recommend to request dynamically from web server as if the url usually would contain a client ID (issued by AWS Cognito, see Step 2, app client ID and secret setting), and by not hardcoding it in the client side, the client can rotate its app client credentials periodically which is generally required for security compliance, without the need to release a new version of client (even though web application does not need installation, it still requires a change to its client artifacts on server side). The login url call is usually returned with a HTTP code of 302 (or newer standard calls for either 303 or 307), and so the browser would redirect to login url automatically and load the login page of Cognito page that you set up in precious article with custom domain prefix for this web server. Once the user provides login credential and click the login button, the Cognito authentication process kicks off. Assuming that user provides a correct login credentials, the process would end up by redirecting browsers back to the callback url set up previously using Cognito (see Step 3, call back url part) with a query parameter named “code”. The callback url is usually set up to be one endpoint exposed by web server, and so once the browser points to this url, it triggers the server side logic to exchange the code for an access token with Cognito, validating that this user is a valid user and optionally the web server can make another call to retrieve extra user info including email, phone number and other custom user attributes, using App Client ID and Secret as client credentials to authenticate with Cognito Auth API. Afterwards, the web server would generate its own session token, and return it to the client. Once the client receives the token, it can use it to request for any protected resources on the server side, and it may opt to store it locally so that the user does not need to re-authenticate if she comes back before the token expires, as explained in previous workflow. Once users no longer requires the application, she may want to terminate the session explicitly by triggering a log out sequence. By logging out explicitly, it notified the web server to invalidate the session token permanently, and so no one can exploit the token for any ill purpose, like described in the following sequence diagram.

Alt Text

To summarize, there are generally 3 webflows related when it comes to login workflow through authorization code grant type using AWS Cognito (or any other Identity Provider). To support these workflows, web server would usually need to expose the following 4 endpoints, with each of them handling their own role and logics.

  • Login url endpoint (Step 4) returns a login url to web or mobile client, pointing to AWS Cognito login page. It usually would contain an app client ID and call back url which points to the exchange code endpoint of web server, that is explained next.
  • Exchange code endpoint(Step 7) exchanges an authorization code for an access token with AWS Cognito, and optionally requests and stores for later use some user information like email, user sub, and custom user attributes if any.
  • Login status endpoint (Step 2) returns the login status of client, by passing in a session token stored locally. If it does not find one stored locally, it would skip this step.
  • Logout endpoint (Step 12) would trigger the process on the web server side to invalidate the session token issued earlier by exchange code endpoint.

Through all 4 endpoints, the access token is never returned directly back to client. Instead, only authorization code which is usually one time use only and short lived is returned to client side, and passed to web server to exchange for an access token through a secure channel, which is never exposed to client sides. Hence, compared to Implicit Grant type, Authorization Code grant type is inherently more secured and recommended as a replacement for Implicit Grant type for both web and mobile applications.

Setting Up Authorization Code Grant Type in AWS Cognito

Now that we know what the login workflows would be if we want to go with Authorization Code grant type, what can we enable this grant type in Cognito. We would follow exactly the same 4 simple steps as described in previous article - Setting up implicit grant workflow in AWS Cognito, step by step when setting up Implicit Grant Type, except that in Step 3 - Config App Client Settings, we want to select Authorization Code grant type instead of (or in addition to) Implicit Grant Type, like in the following snapshot.

Alt Text

As we would need App client ID and secret in order to retrieve login url and user info (see Step 9 in previous section), we also want to note down the app client secret in Step 2 (of previous article), before moving to next section.

Testing Time

Now comes the fun time. We will go through all the different calls in the previous section using browser and curl commands. It will help readers to have better ideas on each step works in authorization code grant type. First, assemble a url in the format of https://<domain prefix>.auth.us-east-1.amazoncognito.com/oauth2/authorize?client_id=<client id>&redirect_uri=https%3A%2F%2Fexample.com&scope=openid&response_type=code. In our case, it would be

https://sunnyoauth.auth.us-east-1.amazoncognito.com/oauth2/authorize?client_id=1vvp0tt53g1uhntoa5bmvnvk2a&redirect_uri=https%3A%2F%2Fexample.com&scope=openid&response_type=code

Copy and paste the above url into Chrome browser, follow the instruction to sign up a new account (for the first time only), or sign in if you have an existing account. Continue to follow the instructions, until you get a url in the format of

https://example.com/?code=<authorization code>

Save the for our next step. Also execute the following command in terminal to create a base64 encoded client credentials, and save it for next step.

echo -n <client id>:<client secret> | base64

It is worth noting that the authorization code is one time use and valid for only 5 minutes. It is designed this way on purpose for security considerations.

Next we will show how we can exchange the authorization code above for an access token, by passing in the base64 encoded client credentials and authorization code. Copy and paste the following curl command and run it through the terminal:

curl --location --request POST 'https://<domain prefix>.auth.us-east-1.amazoncognito.com/oauth2/token' \
--header 'Authorization: Basic <base64 encoded client credentials>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'code=<authorization code>' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'redirect_uri=<callback url>'

For our case, it would be the following url (for security purpose, I exclude the encoded client credentials part).

curl --location --request POST 'https://sunnyoauth.auth.us-east-1.amazoncognito.com/oauth2/token' \
--header 'Authorization: Basic MXZ2cDB0dDUzZzF1aG50b2E1Ym12bnZrMmE6YXBvOW5jYzYwNnAxZDVycGRwdDV1bGxqMnBkdHAyOWg1ZjdmOHZuZmlmNzMycTRpdGFj' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'code=102b28e1-51ea-48f6-bc55-97533d88cf30' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'redirect_uri=https://example.com

And the result will contain an access token as one of fields as shown below:

{
"id_token": "eyJraWQiOiJZSHE1...<others skipped to save space here>",
"access_token": "eyJraWQiOiJmYUd...<others skipeed to save space here>",
"refresh_token": "eyJjdHkiOiJKV1...<others skipped to save space here>",
"expires_in": 3600,
"token_type": "Bearer"
}

With the access token in hand, through the same process in previous article, we can get the user info through /oauth2/userInfo by passing in the access token in “Authorization” http header, with the value in the format of Bearer <access token>. Copy and paste the following curl command and run it through the terminal:

curl -X GET https://sunnyoauth.auth.us-east-1.amazoncognito.com/oauth2/userInfo -H 'Authorization: Bearer <access token>'

And the result is shown below:

{"sub":"95fb5614-18b0-4f48-b49e-d8601934a1df","email_verified":"true","email":"fakeemail@hotmail.com","username":"jinlianwang"}

And the same as pointed out in previous article, the access token is a JWT token and can be inspected using online JWT inspector to see its payload.

Summary

This concludes this quick introduction over how to use authorization code grant type to authenticate users to your web or mobile apps. In summary, compared to implicit grant workflow, it is more complicated to support authorization code grant workflow. Web servers would usually need to expose 4 endpoints, such as login url, login status, exchange code and log out. Using browser and curl command, we showed how an authorization code can be retrieved, and exchanged for an access token in AWS Cognito. Hope that would help you understand how to implement the 4 endpoints for your web server. In next article, we will provide a sample project implementing these 4 endpoints through a AWS Lambda function. Stay tuned!


This content originally appeared on DEV Community and was authored by DEV Community


Print Share Comment Cite Upload Translate Updates
APA

DEV Community | Sciencx (2021-04-25T12:32:52+00:00) User authentication through authorization code grant type using AWS Cognito. Retrieved from https://www.scien.cx/2021/04/25/user-authentication-through-authorization-code-grant-type-using-aws-cognito/

MLA
" » User authentication through authorization code grant type using AWS Cognito." DEV Community | Sciencx - Sunday April 25, 2021, https://www.scien.cx/2021/04/25/user-authentication-through-authorization-code-grant-type-using-aws-cognito/
HARVARD
DEV Community | Sciencx Sunday April 25, 2021 » User authentication through authorization code grant type using AWS Cognito., viewed ,<https://www.scien.cx/2021/04/25/user-authentication-through-authorization-code-grant-type-using-aws-cognito/>
VANCOUVER
DEV Community | Sciencx - » User authentication through authorization code grant type using AWS Cognito. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/04/25/user-authentication-through-authorization-code-grant-type-using-aws-cognito/
CHICAGO
" » User authentication through authorization code grant type using AWS Cognito." DEV Community | Sciencx - Accessed . https://www.scien.cx/2021/04/25/user-authentication-through-authorization-code-grant-type-using-aws-cognito/
IEEE
" » User authentication through authorization code grant type using AWS Cognito." DEV Community | Sciencx [Online]. Available: https://www.scien.cx/2021/04/25/user-authentication-through-authorization-code-grant-type-using-aws-cognito/. [Accessed: ]
rf:citation
» User authentication through authorization code grant type using AWS Cognito | DEV Community | Sciencx | https://www.scien.cx/2021/04/25/user-authentication-through-authorization-code-grant-type-using-aws-cognito/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.