JWT authentication with AWS Cognito and Google
This article will cover the essentials of accessing authenticated endpoints/URL with JWT that uses AWS Cognito & Google as an IdP.
The web application is written in python using flask framework.
The first step will be the configuration of AWS Cognito user pools & Google. The tutorial below from Amazon AWS details the steps to configure AWS Cognito user pools and Google.
AWS Cognito Workflow
Web App Workflow
Step 1: Client will be presented with the Google sign in page.
Step 2: Once authenticated the user will be redirected to authenticated URL/endpoint
Environment Variable Definitions
Note: Cognito url (ref. as <myurl> in the table above) can be found under: AWS Cognito > User Pools > [MyPool] > Domain name > Amazon Cognito Domain
Code walk-through
- Entry point:
The following code composes an URL with a state variable (mitigating cross-site request forgery) and re-direct the request.
2. Configuring callback URL:
Under the callback function, we first check the state variable value to make sure it matches with the one that was passed with the initial request. After that, we extract the code that is part of the URL as a query parameter. We then use the code to get an access token. On successful retrieval of the access token, we will save it as a cookie and redirect the request to our authorized endpoint i.e. user homepage.
3. JWT and Authentication:
The jwt_required decorator is used to confirm the validity of the stored token. In the function definition below we have added some steps to verify the KID and token signature. AWS Cognito generates two RSA keys and uses one of them to sign the token. Therefore, we first extract the KID and signature from the current header and try to match with public keys downloaded from AWS. Once verified, we return the key in PEM format.
4. Test
One important note. If you receive ‘algorithm not supported’ error while accessing an authorized endpoint that means you do not have cryptography package installed that provide basic RS256 algorithm functionality.
The complete code is available on GitHub. Any constructive feedback is welcome.