社内向け Web アプリを作りたい。さらに言えば会社で G Suite (Google Workspace) を契約しているので G Suite アカウントによる SSO でログインできるようにしたい。しかし OAuth2 の認証機能を実装するのは面倒くさい。
そんなとき、OAuth2 Proxy というリバースプロキシを Web アプリの前段に置くという選択肢がある。
これを試してみたく、Docker を使って動作させるところまでやってみたのでその方法をメモしておく。
※ 今回は G Suite による SSO の実装例を書いているが、OAuth2 に対応した IdP ならだいたい同じ方法でできるはず。
コード
コンテナを3つ起動する。
- proxy: OAuth Proxy を動かすコンテナ。今回はポート 8000 で外部からアクセスできるようにする。
- web: Web アプリ。HTTP を喋れればどんな言語/フレームワークで実装されていても問題ない。
- redis: OAuth Proxy のセッションデータを格納する。
version: '3'
services:
proxy:
build: proxy
ports:
- 8000:4180
environment:
OAUTH2_PROXY_HTTP_ADDRESS: 0.0.0.0:4180
OAUTH2_PROXY_PROVIDER: google
OAUTH2_PROXY_CLIENT_ID: 00000000000-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
OAUTH2_PROXY_CLIENT_SECRET: XXXXXXXXXXXXXXXXXXXXXXXX
OAUTH2_PROXY_EMAIL_DOMAINS: example.com
OAUTH2_PROXY_UPSTREAMS: http://web/
OAUTH2_PROXY_COOKIE_SECRET: Tg06aGvkpWU2S_sryFWGYg==
OAUTH2_PROXY_SESSION_STORE_TYPE: redis
OAUTH2_PROXY_REDIS_CONNECTION_URL: redis://redis/
# 以下、HTTPS ではなく HTTP で動かすための設定
OAUTH2_PROXY_COOKIE_SECURE: 'false'
OAUTH2_PROXY_REDIRECT_URL: http://localhost:8000/oauth2/callback
web:
build: web
redis:
image: redis
volumes:
- redis:/data
volumes:
redis:
OAuth2 Proxy はコマンドオプションや設定ファイルなど様々な方法でオプションを指定することができるが、Docker コンテナとして動かす場合は環境変数で指定するのがセオリーだろう。環境変数でオプションを指定する場合は OAUTH2_PROXY_
prefix が必要になる。
Client ID や Client Secret の入手方法は公式ドキュメントに書いてあるので割愛。
今回は雑に試したいだけだったので HTTP で動かしているが、実際に本番環境で動かす際には証明書をマウントして HTTPS で動かせるようにしたほうがよい。
次に、Docker イメージの設定。
[2021.06 追記] 公式の Docker イメージもあるらしい: quay.io/oauth2-proxy/oauth2-proxy
FROM alpine
ARG VERSION=v5.1.1
ARG FILENAME=oauth2_proxy-${VERSION}.linux-amd64.go1.14.2
RUN wget -q https://github.com/oauth2-proxy/oauth2-proxy/releases/download/${VERSION}/${FILENAME}.tar.gz \
&& tar xzf ${FILENAME}.tar.gz \
&& mv ${FILENAME}/oauth2_proxy /bin/ \
&& rm -rf ${FILENAME}*
CMD ["/bin/oauth2_proxy"]
OAuth2 Proxy はビルド済みバイナリをダウンロードするだけでいいのでとても楽。
FROM php:apache
RUN echo "<?php\nphpinfo();" > /var/www/html/index.php
認証後に表示される Web アプリはなんでもいいのだが、例として PHP で phpinfo()
を表示することにした。
動作
docker-compose up
して http://localhost:8000/ にアクセスするとログイン画面が表示される。
ログインに成功すると Web アプリ (今回は phpinfo()
) が表示される。
Web アプリケーションが受け取るリクエストヘッダをみてみると、OAuth2 Proxy 側から X-Forwarded-Email
X-Forwarded-For
X-Forwarded-User
などが送られてきていることがわかる。ログイン中のユーザを識別するだけであればこの情報で十分そう。
メールアドレスとユーザ ID 以外の情報 (例えば、G Suite アカウントに設定されている名前やアイコンなど) を取得したい場合は、 OAUTH2_PROXY_PASS_ACCESS_TOKEN: 'true'
を指定するとリクエストヘッダに X-Forwarded-Access-Token
が付与されてるようになるので、これを利用して API をコールするなどすれば実現できる。
あと気になる点としては、ログイン画面の UI をカスタマイズすることはできないのだろうか。(OAUTH2_PROXY_SKIP_PROVIDER_BUTTON: 'true'
でスキップすることはできるが)