(Illustration: Afternoon-tea with Grilled Halloumi Cheese. Not-so-related to this article, I know XDD. When writing such a long post, you know :p Image source: by Ernest, in London.)
0. Origin
This month Pahud invited us - a group of AWS Hero and AWS Builders to use AWS CDK to code around CloudFront Extensions (CloudFront Lambda@Edge). From my long todo list, I found a topic related to OAuth 2.0 that I have always wanted to do. It's a perfect timing to try and see how to implement a CloudFront Extension solution in AWS CDK (Cloud Development Kit) with .env
environment variable settings, so that you can easily set your favorite IdP (Identity Provider), and then set the parameters generated by the IdP into .env
file. You can use this CloudFront Extension CDK solution to complete the deployment. After practicing, it should be completed within 20 minutes.
This article is organized in order for future education and training material, and is divided into three parts:
- At the beginning, we will introduce use cases, architecture, OAuth 2.0 protocol flow, and Grant Type: Authorization Code process
- Then select and configure a IdP you like (this part is expected to be expanded and updated in the future)
- Finally, "CloudFront Extension OAuth2 Getting Started" takes everyone to actually operate this CDK
1. Use Case
In recent years, the use of static site generators has gradually become a mainstream tool for setting up blogs or document sites. The generated static files, in addition to putting GitHub Pages, another good place is Amazon S3.
Putting Amazon CloudFront as a CDN in front of Amazon S3 is also a common choice.
In some usage scenarios, users are expected to log in before they can view the content of the website or document. In this case, you can request CloudFront Lambda@Edge to help us execute a Lambda program, log in and OAuth 2.0 authorization process with the IdP (Identity Provider) specified by ourselves.
In this case, we will use "Viewer request", one of the four trigger points of CloudFront Lambda@Edge to trigger the execution of the Lambda program we specify to communicate with the IdP. If the OAuth2.0 Authorization Code is successfully authorized, the user will be allowed to watch the origin - the content of website or document.
Then look at two demo videos (corresponding to different IdPs, but both use standard OAuth 2.0 and OpenID) to quickly understand the use case that this article wants to implement:
- The following figure uses Auth0 (IdP) + OAuth2 Authentication (CloudFront Extension) implemented in this article
(This GIF has too many frames, please kindly visit Ernest's origin post: https://www.ernestchiang.com/en/posts/2021/2021-04-13-implementing-cloudfront-lambda-at-edge-oauth2/ )
- The following figure uses self-built KeyCloak (IdP) + OAuth2 Authentication (CloudFront Extension) implemented in this article
- Also use CDK to quickly deploy KeyCloak
(This GIF has too many frames, please kindly visit Ernest's origin post: https://www.ernestchiang.com/en/posts/2021/2021-04-13-implementing-cloudfront-lambda-at-edge-oauth2/ )
2. Amazon CloudFront Extensions
Amazon CloudFront Extensions is a combination of using Lambda@Edge to extend CloudFront to implement various rich features. Originally implemented using AWS CloudFormation, but this time Pahud invited us to use the AWS CDK method to implement it.
The git repo we implemented this time is placed in Pahud's home: https://github.com/pahud/cdk-cloudfront-plus
The name of the extension I implemented this time is "OAuth2 Authentication", project number "SO8131", directory name "cf-authentication-by-oauth2".
The goal of implementation is to create a universal package (Lambda@Edge), which can be set to correspond to various parameters provided by IdP (Identity Provider) by setting environment variables, such as client id, client secret, callback URL, etc. And hope to reduce package dependencies and use TypeScript throughout.
3. OAuth 2.0 Grant Type: Authorization Code
RFC6749 defines The OAuth 2.0 Authorization Framework, OpenID implemented OAuth 2.0 and integrated account information. Simply understand that OAuth 2.0 is a theory, and OpenID is one of the implementation methods based on this theory.
OAuth 2.0 defines four roles, six steps, Three round trips. Refer to the following Protocol Flow:
- Client: Authorization Request --> Resource Owner: Authorization Grant
- Client: Authorization Grant --> Authorization Server: Access Token
- Client: Access Token --> Resource Server: Protected Resource
Quick summary: three simple steps: first take a code --> take the code for a (access) token --> take the token for resources.
OAuth 2.0 defines four Authorization Grant Types:
-
Authorization Code
- Authorization Code
- Authorization Code with PKCE
- Implicit
- Resource Owner Password Credentials
- Client Credentials
Quick summary: The context in this article is suitable for Authorization Code.
After establishing the process structure and narrowing down the scope of using the Authorization Code, then set up the IdP you choose, create a client in the IdP environment, and obtain various environmental variables of the IdP and the client.
In the process, we will encounter various IdP hidden magic logic, oh no, I mean IdP, in order to strengthen the verification process, there will be different details that need to be paid attention to. E.g
- The Auth0 document does not mention but the authorize parameter combination must be
response_type=code
withscope=openid
to get the JWT token. (reference source) - KeyCloak stipulates which URL the Client comes from at the beginning, and the subsequent specified
redirect_uri
must be exactly the same URL before releasing, otherwise KeyCloak will keep spraying400 Bad Request
with a mysterious and unknown error log:[0m[33m11:57:34,772 WARN [org.keycloak.events] (default task-97) type=CODE_TO_TOKEN_ERROR, realmId=RealmDemoCDK, clientId=demo-cloudfront-plus, userId=2ae58a4c-9b3e-4f0e-b58d-b9462e73105a, ipAddress=10.0.9.157, error=invalid_code, grant_type=authorization_code, code_id=fbb08df8-1af1-4960-a9ac-ab80e0b3d377, client_auth_method=client-secret
. (reference source)
Please visit my blog to continue the section #4 ~ #7...
Top comments (0)