TL;DR: get an applic­a­tion load bal­an­cer, add an HTTPS listener (you will need a web domain and an SSL cer­ti­fic­ate for that), add a rule to the load bal­an­cer to first authen­tic­ate using OIDC, then for­ward to your site. Voila! 

Ima­gine you have built a small web app includ­ing a web inter­face that you want to make avail­able for all your col­leagues. You would like to host it on Amazon Web Ser­vice (AWS). And of course, you want to make sure only your col­leagues can access it! Let us also say that you want your users to log in via Single-Sign-On with their reg­u­lar Microsoft accounts, which are part of your company’s Azure Act­ive Directory. 

If you have ever done research on the web about authen­tic­a­tion on AWS, you will have noticed the seem­ingly infin­ite num­ber of dif­fer­ent ways to go, and of dif­fer­ent tools to help you. You may have come across AWS Cog­nito, AWS SSO, AWS Amp­lify, AWS API Gate­way, AWS Dir­ect­ory Ser­vice, …, plus you may have seen a myriad of com­plic­ated authen­tic­a­tion flow dia­grams about cook­ies, tokens et cet­era. You will surely also have come across many pro­pri­et­ary web­sites that offer their own products and ser­vices in order to secure your website. 

But it does not have to be so com­plic­ated. The rest of this art­icle is going to show a con­veni­ent way of set­ting up SSO authen­tic­a­tion using your Azure AD accounts via OIDC without writ­ing a single line of code. The main inspir­a­tion for this came from this AWS blog post, but we will be try­ing to add a few details for clarity. 

Step 0: Deploy your web app in AWS 

Before start­ing to add authen­tic­a­tion, get your web app up and run­ning. In this art­icle, we are going to assume the applic­a­tion is hos­ted on an EC2 instance, but of course, you may also use con­tain­ers in EKS or other means. 

Place the EC2 instance in a private secur­ity group – allow SSH con­nec­tions (ideally only from your IP), but do not allow any TCP or other con­nec­tions so far. 

Step 1: Set up the Load Balancer 

In the AWS EC2 dash­board, the left-hand menu should provide you with a “Load Bal­an­cing” menu. Under the subitem “Load Bal­an­cers”, go ahead and cre­ate a new load bal­an­cer. Choose “Applic­a­tion Load Bal­an­cer” (ALB) as its type. Choose “inter­net-facing” and add an HTTPS listener.  

Note that you are going to need at least two avail­ab­il­ity zones in your VPC for the load bal­an­cer to be cre­ated. If you do not have this, go to your VPC and add a sub­net with a dif­fer­ent avail­ab­il­ity zone. 

On the “Con­fig­ure Secur­ity Set­tings” side, it will ask you to provide an SSL/TLS cer­ti­fic­ate and offers to take you to the AWS Cer­ti­fic­ate Man­ager (ACM). Fol­low the link and cre­ate a cer­ti­fic­ate. Note that you must have a web domain for this pur­pose – one for which you have con­trol over the DNS con­fig­ur­a­tion. A pub­lic IP and DNS name of an EC2 instance (….compute.amazonaws.comdoes not work! Note also that you can cre­ate SSL cer­ti­fic­ates else­where, too, e.g. on letsencrypt.org, then add it to ACM. 

Place the ALB in a new secur­ity group of its own – one that allows inbound access via HTTPS on port 443 from all addresses. 

Under “Con­fig­ure Rout­ing”, you will need to cre­ate a “Tar­get Group” that includes your web applic­a­tion – i.e. your EC2 instance along with the port that the applic­a­tion is exposed on. Select HTTPS or HTTP, depend­ing on how you are expos­ing your application. 

Step 2: Con­fig­ure authen­tic­a­tion and for­ward­ing in the load balancer 

Choose your newly cre­ated load bal­an­cer in the EC2 load bal­an­cing menu and go to tab “Listen­ers”. Add a new listener: set it to listen for all traffic on port 443. As default action, choose “Authen­tic­ate” and then “OIDC”. Now you will see a lot of fields to be filled (Issuer, Author­iz­a­tion end­point, …) – and this is when you need to jump over to your OIDC pro­vider. In our case, our company’s Microsoft Azure Act­ive Directory. 

In your Azure portal, find the Azure Act­ive Dir­ect­ory. In the menu bar to the left, find the entry “App regis­tra­tions” and start a new regis­tra­tion. This is where you can define who will be able to access your app, for example only accounts from your organ­isa­tion. Import­ant: fill the optional “Redir­ect URI” with https://<your_sites_domain>/oauth2/idpresponse (see also here). 

Once the app is registered, its page in the Azure AD will provide you all the end­points and inform­a­tion you need to com­plete the “Authen­tic­ate” rule in your load balancer. 

Once com­plete, add a second action under­neath: “For­ward” to your EC2 instance. 

Step 3: Allow the load bal­an­cer to talk to your EC2 instance. 

You’re almost there – now we just revisit the secur­ity group set­tings for your EC2 instance and add a rule for incom­ing HTTPS traffic only from our new load bal­an­cer. Or, for con­veni­ence, select the secur­ity group of the load bal­an­cer (assum­ing you have only the load bal­an­cer in it!). As a port, select the port that your web applic­a­tion is exposed to. 

Step 4: Test 

When you now enter your web domain in a browser, you should be redir­ec­ted to a Single-Sign-On page by Microsoft (or the OIDC pro­vider you chose). Incor­rect or invalid cre­den­tials should give you an error mes­sage, cor­rect cre­den­tials should lead you to be able to see your applic­a­tion. Congratulations! 

Final remarks 

You now have a deployed ver­sion of your applic­a­tion, pro­tec­ted by a power­ful authen­tic­a­tion mech­an­ism, includ­ing multi-factor authen­tic­a­tion or sim­ilar if those are set up in your authen­tic­a­tion provider. 

I hope you have found this way of achiev­ing this con­veni­ence! Using a load bal­an­cer in front of the applic­a­tion can of course provide other bene­fits, too. Should you ever scale your applic­a­tion to run on mul­tiple machines, the load bal­an­cer can fol­low its real call­ing. But even with only one applic­a­tion instance run­ning behind it, it has the advant­age of hand­ling all authen­tic­a­tion-related inter­ac­tions with cli­ents, while strain­ing your application’s EC2 instance only with applic­a­tion-related requests. Just note that Load Bal­an­cers do cost money (check https://calculator.aws/#/) and that they can­not be turned off – so if you intend to have your applic­a­tion or EC2 instance run­ning only on demand, con­sider cre­at­ing an Infra­struc­ture-as-Code stack in Cloud­Form­a­tion or Ter­ra­form to cre­ate your load bal­an­cer swiftly. 

Feel free to reach out and let me know what you think!