Over the course of my technical career, I’ve always thought of Oauth2 to, frankly, be a bit of a pain. Oauth2 offers a mind boggling amount of possibilities and is the basis of many authorization workflows.
However, I have found the documentation and supporting examples of how to integrate Oauth2 somewhat lacking. I hope that someone out in the ether will find this blog post and save a few days of keyboard smashing.
First, the backstory: We needed to deploy an application into a Kubernetes Cluster with no native authentication or authorization. It was an application to which everyone in Agari’s engineering organization needed access, so the authorization workflow needed to be easy to use and robust.
Enter OKTA. For those of you that aren't familiar with OKTA, it’s a cloud-based identity service that supports Oauth 2.0 workflows. The concept was fairly simple. We would deploy our handy little application into one of our Elastic Kubernetes Service (EKS) clusters, give it an ingress via an Application Load Balancer (ALB), and configure the ingress rules to integrate with OKTA.
This way, everyone could use their existing OKTA logins to access our new application. In addition, my team, Site Reliability Engineering (SRE), needed to programmatically access the same endpoint to configure our little application via an API. While provisioning user access to the application was a fairly straightforward process, getting programmatic access was a bit harder.
For starters, we needed to deploy our application and get it configured for Okta. I won't go into great detail here as there are lots of ways to do this and tons of documentation on the interwebs.
It boils down to three steps:
- Deploy your application: We used Helm, Kubernetes, and AWS ALBs
- Configure OKTA: Create a new application in OKTA for the application you are trying to protect (you can find more here); you will use the information from this step on step 3
- Configure the ALB: In order to authentic users, a rule must be added before forwarding the incoming HTTPS request to the application we are trying to protect (more here)
Now for The Fun Stuff: How to Get Programmatic Access
The following steps were done in Python3 with the requests library:
-
- Login to OKTA with the authn api and grab the session token
auth_payload = {“username”: “someawesomename”, “password”: okta_password}
response = requests.post(f”{OKTA_URL}/api/v1/authn”, json=auth_payload)
sessiontoken = response.json().get(‘sessionToken’)
- Login to OKTA with the authn api and grab the session token
-
- Use the session token to get authorized to the application
authorize_payload = {“response_type”: “id_token”, “scope”: “openid”, “prompt”: “none”, “client_id”: okta_client_id, “redirect_uri”: url, “sessionToken”: sessiontoken, “state”: “xyz”, “nonce”: “abc”}
cookie = requests.get(f”{OKTA_URL}/oauth2/v1/authorize”, authorize_payload, allow_redirects=False)
- Use the session token to get authorized to the application
-
- Grab the session cookie from the ALB
response = requests.get(f”{your_applicaiton_url}/api/getSomething”, cookies=jar)
alb_cookie = response.history[-1].cookies[‘alb-YOURAPP-cookie-0’]
- Grab the session cookie from the ALB
-
- Set the cookie for other requests
jar = requests.cookies.RequestsCookieJar()
jar.set(“alb-YOURAPP-cookie-0”, alb_cookie)
resp = requests.post(f”{YOURAPP}/api/setSomething”, cookies=jar, json=payload)
- Set the cookie for other requests
That's it! While this solution may not be overly complex, the documentation on how to do it is mediocre at best. I hope this clarifies how to programmatically provision access to applications protected by Okta and AWS ALBs.
This solution, and many others like it, help Agari to protect against email based advanced phishing and social engineering attacks.