Authentication is always an important topic, basically, any website needs authentication function. Traditionally, we need to maintain our own database, frontend, backend and middleware to achieve complete authentication. But thanks to OAuth, we now have many easy options, such as using Google accounts for authentication.
In this article, we would like to introduce a way to make any website have Google authentication without any modification.
Why is there a need for this? Sometimes we can easily deploy a tool to the cloud, but we don't want the tool to be available for public access, so we want to add authentication to it. However, we don't want to modify the tool's code, so we're attempting to find a more efficient way to do this.
For example, Apache Flink is a powerful and easy to develop streaming framework that provides a fully functional web portal. Nevertheless, the web portal has no authentication mechanism, so anyone who can access it can upload jobs.
The official documentation recommends several approaches to mitigate this downside, but those approaches are too lightweight, on the other hand, to provide a full authentication mechanism, Flink supports Kerberos integration which is too heavy. Therefore, we need a plugin that makes it easy for a website to support common authentication.
Solution Concept
From the above diagram, we can find out a user does not access the service directly, but through a Proxy, which verifies and determines whether to allow access.
Therefore, we do not need to modify the code of the service, we just need to plug a Proxy in front to achieve our goal.
In fact, there are many Proxies that provide this function, in this article we choose the most common one OAuth2 Proxy, and use Google OAuth as an example.
Setup Step by Step
First, we need to go to Google Cloud Console to create a new project, the process is not difficult, just fill it out.
Next, navigate to Credentials
under API & Service
and create a new credential. There is only one field that needs careful consideration, Redirect URL
, here fill in the http://localhost:4180/oauth2/callback
that is needed for the example.
Please remember the Client ID
and Client Secret
after you finish creating, we will need them later.
Now, let's use a simple web app as an example, which is the hello-app
provided by Google.
version: '3'
services:
hello-world:
image: gcr.io/google-samples/hello-app:1.0
ports:
- "8080:8080"
Running this docker-compose.yml
should start hello world, and you can see the corresponding message at http://localhost:8080
. At this point, the web app is working without authentication.
Let's add a Proxy to implement authentication.
services:
oauth2-proxy:
ports:
- "4180:4180"
image: bitnami/oauth2-proxy:7.3.0
command:
- --http-address
- 0.0.0.0:4180
environment:
OAUTH2_PROXY_UPSTREAMS: "http://hello-world:8080/"
OAUTH2_PROXY_CLIENT_ID: <YOUR_CLIENT_ID>
OAUTH2_PROXY_CLIENT_SECRET: <YOUR_CLIENT_SECRET>
OAUTH2_PROXY_COOKIE_SECRET: <A_STORNG_SALT>
OAUTH2_PROXY_HTTPS_REDIRECT: "false"
OAUTH2_PROXY_EMAIL_DOMAINS: "*"
OAUTH2_PROXY_PROVIDER: "google"
OAUTH2_PROXY_REDIRECT_URL: "http://localhost:4180/oauth2/callback"
restart: always
There are three fields to fill in this example, including the Client ID
and Client Secret
just mentioned, as well as the secret needed by a proxy, if there is no special need, then just generate it. I am using a Python script to generate, in fact, there are many ways, choose the one you are familiar with.
import secrets
print(secrets.token_hex(16))
Just launch this docker compose directly after completion. You can find that if you access http://localhost:4180
, you will be redirected to Google Authentication. Once authenticated, you can see the original hello world result.
Finally, we can close the originally opened 8080 port. Here is a complete docker-compose.yml
, copy and paste it directly with minor modifications and it will work.
version: '3'
services:
hello-world:
image: gcr.io/google-samples/hello-app:1.0
ports:
- "8080"
oauth2-proxy:
ports:
- "4180:4180"
image: bitnami/oauth2-proxy:7.3.0
command:
- --http-address
- 0.0.0.0:4180
environment:
OAUTH2_PROXY_UPSTREAMS: "http://hello-world:8080/"
OAUTH2_PROXY_CLIENT_ID: <YOUR_CLIENT_ID>
OAUTH2_PROXY_CLIENT_SECRET: <YOUR_CLIENT_SECRET>
OAUTH2_PROXY_COOKIE_SECRET: <A_STORNG_SALT>
OAUTH2_PROXY_HTTPS_REDIRECT: "false"
OAUTH2_PROXY_EMAIL_DOMAINS: "*"
OAUTH2_PROXY_PROVIDER: "google"
OAUTH2_PROXY_REDIRECT_URL: "http://localhost:4180/oauth2/callback"
restart: always
If the function is not working properly, it is possible that Google's OAuth client needs start time, wait for it a little.
Conclusion
This article is a real example of what can be done, and it is quite straightforward.
Nevertheless, it is important to accomplish our goal to add authentication to any web app. For this example, we chose Google OAuth as the easiest to implement, but actually OAuth Proxy supports a lot of IDPs, and there is a complete list in the official document.
To understand this article, you don't even need any background knowledge of OAuth, just follow the steps. Enjoy.
Top comments (2)
Hi, was helpful inteed. Just an addition if you are playing around http only mode then the following env var should be set as well (otherwise will endup with a 403 error)
OAUTH2_PROXY_COOKIE_SECURE: "false"
NB: only for http
Thanks for the addition.