In this section we will be building API Access Control with Amazon Cognito. This will extend our architecture to ensure that only identified users are permitted access to the API.
Even though we have controlled traffic at multiple layers, anyone who knows your CloudFront Domain Name can access your API. Furthermore we do not know who accessed your API, so the owner of the traffic remains anonymous. Ideally we should ensure that only legitimate users who we are aware of are permitted access. This will mean that a successful API call will have to be both identified as well as authorized.
In this lab we will build out our architecture using Amazon Cognito. This addition will allow a user to sign in to a user pool which we create, obtain an identity or access token and then call the API method with one of the tokens. These tokens are typically set to the request’s Authorization header.
The second CloudFormation template which you have already deployed already contains an Amazon Cognito User Pool. We will start by obtaining the App client secret of Cognito, which we will use to generate an ID token at later points in the lab.
Take note of App client secret. Other required values such as user pool ID and App client ID are available in the Output section of the current cloudformation stack. Record these before moving to the next step.
Amazon Cognito user pools are used to control who can invoke REST API methods. We now need to integrate the API with the Amazon Cognito user pool.
Go to API Gateway in the AWS console and select API called wa-lab-rds-api.
From the main navigation pane, choose Authorizers and click Create New Authorizer button.
Your configuration should be similar to the screenshot below:
Before you click Method Request, ensure that you refresh your browser. If you do not do this, our new Authorizer will not appear when trying to associate with Method Request.
Select Method Request as shown:
Select Development stage as Dev from the drop-down list. Click Deploy.
Your API is now using COGNITO_USER_POOLS as Authorizer. Only users registered in COGNITO_USER_POOLS can access your API.
By default, CloudFront doesn’t consider headers when caching your objects in edge locations. Now your request must have an Authorization header with a valid ID Token to access API. Therefore, we need to configure CloudFront to forward headers to the API Gateway. Further details on this can be found here
If you test out without Authorization header now, you will still see data being returned as it’s served from CloudFront edge caches. Let’s invalidate files to prevent this from happening.
After successful completing authentication, Amazon Cognito returns user pool tokens to your app. You can use these tokens to grant your users access to the API Gateway. Amazon Cognito user pools implements ID, access, and refresh tokens as defined by the OpenID Connect (OIDC) open standard.
In this lab, we will use an ID Token that is a JSON Web Token (JWT) that contains claims about the identity of the authenticated user such as name, email, and phone_number.
python sendRequest.py 'CloudFrontEndpoint'
You will get “Unauthorized” response with 401 response code.
You must send Authorization header with valid ID token to access API now.
python getIDtoken.py <username> <user_password> <user_pool_id> <app_client_id> <app_client_secret>
You should be able to generate ID Token successfully. This will be valid for 60 minutes.
python sendRequest.py 'CloudFrontEndpoint' ID_Token
You should be seeing your data as expected with a 200 response code. Now you must have provided an ID Token as the Authorization header to access your API only through CloudFront.
Ensure that you complete the tear down instructions in the final section to remove resources created in this lab.
END OF SECTION 5