What is ecommerce merchandising? Key components and best practices
A potential customer is about to land on the home page of your ecommerce platform, curious to see what cool ...
Search and Discovery writer
A potential customer is about to land on the home page of your ecommerce platform, curious to see what cool ...
Search and Discovery writer
By now, everyone’s had the opportunity to experiment with AI tools like ChatGPT or Midjourney and ponder their inner ...
Director, Product Marketing
Search has been around for a while, to the point that it is now considered a standard requirement in many ...
Senior Machine Learning Engineer
With the advent of artificial intelligence (AI) technologies enabling services such as Alexa, Google search, and self-driving cars, the ...
VP Corporate Marketing
It’s no secret that B2B (business-to-business) transactions have largely migrated online. According to Gartner, by 2025, 80 ...
Sr. SEO Web Digital Marketing Manager
Twice a year, B2B Online brings together industry leaders to discuss the trends affecting the B2B ecommerce industry. At the ...
Director of Product Marketing & Strategy
This is Part 2 of a series that dives into the transformational journey made by digital merchandising to drive positive ...
Benoit Reulier &
Reshma Iyer
Get ready for the ride: online shopping is about to be completely upended by AI. Over the past few years ...
Director, User Experience & UI Platform
Remember life before online shopping? When you had to actually leave the house for a brick-and-mortar store to ...
Search and Discovery writer
If you imagine pushing a virtual shopping cart down the aisles of an online store, or browsing items in an ...
Sr. SEO Web Digital Marketing Manager
Remember the world before the convenience of online commerce? Before the pandemic, before the proliferation of ecommerce sites, when the ...
Search and Discovery writer
Artificial intelligence (AI) is no longer just the stuff of scary futuristic movies; it’s recently burst into the headlines ...
Search and Discovery writer
Imagine you are the CTO of a company that has just undergone a massive decade long digital transformation. You’ve ...
CTO @Algolia
Did you know that the tiny search bar at the top of many ecommerce sites can offer an outsized return ...
Director, Digital Marketing
Artificial intelligence (AI) has quickly moved from hot topic to everyday life. Now, ecommerce businesses are beginning to clearly see ...
VP of Product
We couldn’t be more excited to announce the availability of our breakthrough product, Algolia NeuralSearch. The world has stepped ...
Chief Executive Officer and Board Member at Algolia
The ecommerce industry has experienced steady and reliable growth over the last 20 years (albeit interrupted briefly by a global ...
CTO @Algolia
As an ecommerce professional, you know the importance of providing a five-star search experience on your site or in ...
Sr. SEO Web Digital Marketing Manager
Mar 21st 2022 engineering
Our team recently implemented an internal static website that allows employees to download technical reports. Since we’re heavy AWS (Amazon Web Services) users, we naturally decided to host it on AWS S3, which provides a dedicated feature to build static websites (S3 static website hosting).
Very quickly, however, we ran into an issue: AWS S3 does not provide any native, out-of-the-box authentication/authorization process. Because our website was going to be internal-only, we needed some kind of authorization mechanism to prevent non-authorized users from accessing our website and reports.
We needed to find a solution to secure our internal static website on AWS S3.
We use Okta for all Identity and User Management, so whatever solution we found had to plug-in with Okta. Okta has several authentication/authorization flows, all of which require the application to perform a back-end check, such as verifying that the response/token returned by Okta is legitimate.
So we needed to find a way to carry these checks/actions on a static website which uses a back end that we don’t control. That’s when we learned about AWS Lambda@Edge, which lets you run Lambda Functions at different stages of a request and response to and from Amazon Cloudfront:
As the diagram indicates, we can trigger a Lambda Function at four different stages:
viewer-request
)origin-request
)origin-response
)viewer-response
)We saw a solution to our original issue: trigger a Lambda at the viewer-request
stage that would check if the user is authorized.
There were two conditions:
We’ll cover here the key elements and main issues we faced. The complete code is available here. Feel free to use it in your project!
As we developed the solution, we ran into several restrictions and caveats of Lambda@Edge.
Lambda@Edge Functions cannot use environment variables. That meant that we needed to find another way for making data transfers in our function. We opted for SSM parameters and templated parameter names in the Node.js code (we use Terraform to render the template when deploying the Lambda Function).
For viewer events (reminder: we use the viewer-request
event), the Lambda package can be 1 MB at most. One MB is pretty small considering that it includes all dependencies (except of course the runtime/standard library) of your Lambda Function.
That’s why we had to rewrite our Lambda in Node.js instead of the original Python, because the Python package with its API and other dependencies exceeded the 1 MB limit.
Lambda@Edge functions can only be created in the us-east-1
region. It’s not a big issue but it means you’ll need to:
provider
to access the bucket you want to protect if it’s not in us-east-1
The IAM execution role associated with the Lambda@Edge functions must allow the principal service edgelambda.amazonaws.com
in addition to the usual lambda.amazonaws.com
. See AWS – Setting IAM permissions and roles for Lambda@Edge.
Once we managed the above restrictions and caveats, we focused on the authorization/authorization.
Okta offers several ways to authenticate and authorize users. We decided to go with OAuth2, the industry-standard protocol for authorization.
Note: Okta implements the OpenID Connect (OIDC) standard, which adds a thin authentication layer on top of OAuth2 (that’s the purpose of the ID token mentioned hereafter). Our solution would also work with pure OAuth2 with minimal modifications (removal of the ID token use in the code).
OAuth2 itself offers several authorization flows depending on the kind of application using it. In our case, we needed the Authorization Code flow.
Here is the complete diagram of the Authorization Code flow taken from developer.okta.com that shows how it works:
To summarize the flow:
So far we have a working authorization process; however, we need to check the access/ID token on every request (a malicious user could forge an invalid cookie or tokens). Checking the tokens means sending a request to Okta and waiting for the response on every page the user visits, which slows down the latency of Cloudfront CDN and loading times significantly and is clearly sub-optimal.
Note: While local verification of the Okta token is theoretically possible, as of this writing the SDK provided by Okta uses a LRU (in-memory) cache when fetching the keys used to check the tokens. Because we’re using AWS Lambda, and the memory/state of the program isn’t kept between invocations, the SDK is useless to us: it would still send one HTTP request to Okta for every user request, to retrieve the JWKs (JSON Web Keys). Worse, there’s a limitation of 10 JWK requests per minute, which would make our solution stop working if there were more than 10 requests per minute.
To resolve this, we decided to use JSON Web Tokens, as we did for our admin application. The initial authorization process is the same except that, instead of saving the access/ID tokens into a cookie, we create a JWT containing these tokens, and then save the JWT into a cookie.
Since the JWT is cryptographically signed:
The JWT has a relatively short pre-defined expiration time to avoid having a valid JWT containing expired or revoked access/ID tokens. Another option would be to check the access/ID tokens regularly and revoke the associated JWT if needed, but then we would need a revocation mechanism, which makes things more complex.
Finally, as suggested above, the tokens provided by Okta have an expiration time. It is possible to transparently renew them using a refresh token (so the user doesn’t have to re-login when the tokens expire) but we didn’t implement that.
While adding OAuth2 authentication to an S3 static bucket with Okta (or any other OAuth2 provider) is possible in an AWS-integrated and secure manner, it’s certainly not straightforward.
It requires writing a middleware between AWS and the OAuth2 provider (Okta in our case) using Lambda@Edge. We had to do the following ourselves:
Finally, a bunch of AWS resources must be created to glue everything together and make it work.
All this was worth the effort, because it works and our website is now more secure.
You can find the code of the Lambda@Edge as well as the infrastructure (Terraform) here: https://github.com/GuiTeK/aws-s3-oauth2-okta.
Powered by Algolia Recommend