The aim of this workshop is, on one hand, show you how you can integrate the authentication in an API Gateway. On the other hand, we will explore different authorization mechanisms used by the API Gateway.
In this workshop you will learn:
Overall, you will learn how to create a secure and customizable API Gateway. Additionally, you will have experimented with multiple security options that API Gateway provide us and which are usually useful in many projects.
According to the AWS Documentation:
Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale. APIs act as the “front door” for applications to access data, business logic, or functionality from your backend services. Using API Gateway, you can create RESTful APIs and WebSocket APIs that enable real-time two-way communication applications. API Gateway supports containerized and serverless workloads, as well as web applications.
According to the AWS Documentation:
Amazon Cognito lets you add user sign-up, sign-in, and access control to your web and mobile apps quickly and easily. Amazon Cognito scales to millions of users and supports sign-in with social identity providers, such as Facebook, Google, and Amazon, and enterprise identity providers via SAML 2.0.
Access control to AWS resources: You can define roles and map users to different roles so your app can access only the resources that are authorized for each user
Standards-based authentication: It uses uses identity management standards including OpenID Connect, OAuth 2.0, and SAML 2.0
Adaptive authentication: when Amazon Cognito detects unusual sign-in activity, such as sign-in attempts from new locations and devices, it assigns a risk score to the activity and lets you choose to either prompt users for additional verification or block the sign-in request
Protection from compromised credentials: When Amazon Cognito detects users have entered credentials that have been compromised elsewhere, it prompts them to change their password
Supports Multiple Compliance Programs: It is HIPAA eligible and PCI DSS, SOC, and ISO/IEC 27001, ISO/IEC 27017, ISO/IEC 27018, and ISO 9001 compliant.
(for more details about these components, visit the AWS Documentation)
First of all, we need to set up the environment to continue with this lab. We need to first clone the repository https://github.com/ronaldtf/aws-auth-apigateway
$> git clone https://github.com/ronaldtf/aws-auth-apigateway.git
The directory structure is as follows:
In order to set up the infrastructure, we can opt for one of these methods:
Before running the script, we need to verify that we have our environment ready to launch it. You should check that you have installed and configured the following tools:
AWS Command Line Interface:: AWS CLI is a tool that let us send requests to AWS API to perform certain actions. Regarding the operating system you use, you can either download the installer and install it or use the pip
installer. To get details instructions of how to do this follow the AWS Command Line Interface page. For instance, for Unix OS, you need Python3 and pip to be installed. Then, execute:
$ pip install awscli
$ pip install aws-mfa
We need to set up our environment to later be able to deploy our resources. To do so, we must follow the AWS documentation. We describe below the procedure anyway.
In the IAM Section in the AWS Console, we have to go to users and select the user we want to use for the deployment. We select Security credentials
and Create access key
(if not previously created). Copy the user access key
and secret access key
provided.
If you do not find the file
~/.aws/credentials
in the cases below, type:
$ aws configure
and set the default region (e.g. eu-west-1).
If you are not using MFA and simply use an account for users and services (which is not recommended), just set the values copied above in an ~/.aws/credentials
file:
[default]
aws_access_key_id = YOURACCESSKEYID
aws_secret_access_key = YOURSECRETACCESSKEY
If you use MFA and a user account for the IAM users and a service account for the services (and where you want to deploy your services) as shown in the image below…
… you must follow this configuration:
$ pip install aws-mfa
[profile default]
...
[profile lab-long-term]
region = eu-west-1
output = json
role_arn = arn:aws:iam::123456789012:role/role_to_be_assumed
source_profile = default
NOTE: the
source_profile
is the profile that gives us permissions to do an assume role. Therefore, we need to define those credentials for it in the~/.aws/config
file.
[lab-long-term]
aws_access_key_id = YOURACCESSKEYID
aws_secret_access_key = YOURSECRETACCESSKEY
aws_mfa_device = arn:aws:iam::123456789012:mfa/iam_user
aws-mfa --profile lab
This will place the right credentials in the ~/.aws/credentials
file. However, note that this credentials will expire and we will need to execute the command below again once they are expired.
Before running the script, we need to edit it and set the following parameters:
The, we simply run the script:
$> ./deploy.sh
Create a bucket and place the python.zip
file in that bucket
Go to the CloudFormation service, and deploy a stack by selecting the deploy.yaml
file placed in the deployment
directory. Pass the name of the created bucket as a parameter
Once done, you have to get the output of the Stack and fill in the values of the variables in web/js/config.js
Upload the test.json
file to the S3 bucket indicated in the output (key: ReferredBucket
.
In order to do the test, you need to create a user in Cognito
NOTE: User name must be an email address!
In order to test this example, we will use 2 methods:
Authorization
header to your request)The procedure of how to perform this will be explained during the workshop
In this case, we will test the example by using the example page (doing it with the curl command is possible, but complex).
Following the Part 1, will you be able to configure this case?
API keys are alphanumeric string values that you distribute to application developer customers to grant access to your API. You can use API keys together with usage plans or Lambda authorizers to control access to your APIs. API Gateway can generate API keys on your behalf, or you can import them from a CSV file.
In order to test this example, we will use 2 methods:
X-API-Key
header to your request)To implement this, you need:
To test this, use a new API Gateway resource and method. You can reuse the default public lambda as the backend for this case.
NOTE: Bear in mind that, after you have changed the created method by using the API key, you need to redeploy your API Gateway
For generating a custom token, visit JWT IO page
Do you know how to customize your current authorizer to validate your custom token (instead of the one provided by Cognito)?
NOTE: There is already a lambda implemented to validate the custom token (named
<stack_name>-authorizer
). This authorizer only acceptsHS256
encoded tokens (bear that in mind, otherwise it would not work)
IMPORTANT: If you are going to use Cognito tokens, you must:
- Change the token type to HS256 (the implemented custom authorizer only support this encryption type)
- Remove the aud field (otherwise, we will get an error
Invalid audience
)
For this case, we will only use the
curl
command to test it. Remember to useAuthorization
header to add the token in the authorizer (otherwise, it will not work)
Extracted from AWS Documentation
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:region:account-id:api-id/",
"Condition": {
"IpAddress": {
"aws:SourceIp": ["192.0.2.0/24", "198.51.100.0/24" ]
}
}
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "",
"Action": "execute-api:Invoke",
"Resource": [
"arn:aws:execute-api:region:account-id:api-id/"
],
"Condition" : {
"StringEquals": {
"aws:SourceVpc": "vpc-2f09a348"
}
}
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:region:account-id:api-id/",
"Condition": {
"IpAddress": {
"aws:SourceIp": ["192.0.2.0/24", "198.51.100.0/24" ]
}
}
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": [
"arn:aws:execute-api:region:account-id:api-id/"
],
"Condition" : {
"StringNotEquals": {
"aws:SourceVpce": "vpce-1a2b3c4d"
}
}
}
]
}
This lab goes beyond the purpose of the workshop. However, I have found interesting to include a section here.
This is the procedure:
Create a private API Gateway and a mock resource
Create an interface endpoint (execute-api) to the API Gateway to be used within a VPC
To grant access to your VPC endpoint, create a resource policy and attach it to your API
From an EC2 instance from your VPC, call a method by using curl
and the interface endpoint as an endpoint
Now that you know…
… it’s time to put your hands on new projects and start new challenges!