bitly/oauth2_proxyを用いて,ウェブアプリケーションに手っ取り早くOAuth2認証を導入するという話です.
oauth2_proxyは良い感じでOAuth2による認証を肩代わりしてくれる君で,何らかのリバースプロキシの認証機構と組み合わせて利用すると簡単にOAuth2ログインを実現することができます.
今回は例としてKibanaにGoogleのOAuth2ログインを導入してみたいと思います.
構成
- Kibana
 - bitly/oauth2_proxy
 - nginx
 
+------+              +-------+               +--------------+            +--------+
|      |              |       | ----auth----> |              |            |        |
| user | --request--> | nginx |               | oauth2_proxy | <--auth--> | Google |
|      |              |       | <--response-- |              |            |        |
+------+              +-------+               +--------------+            +--------+
                          |
                       access
                          |
                          v
                      +--------+
                      |        |
                      | kibana |
                      |        |
                      +--------+
流れ
事前準備
https://console.developers.google.comにアクセスしてcredentialsを作り,Client IDとClient secretを取得します.この時,Authorized redirect URIsにリダイレクト先のURLを登録しておきます (e.g. https://kibana.example.com/oauth2/callback).
実際に動くサンプル
docker-composeで実際に動くものを示します.
nginx.conf
| user nginx; | |
| pid /var/run/nginx.pid; | |
| worker_processes auto; | |
| events { | |
| use epoll; | |
| } | |
| http { | |
| server { | |
| listen 80; | |
| server_name kibana.example.com; | |
| location ~ ^/oauth2/(?:auth|start)$ { | |
| internal; | |
| proxy_pass http://oauth2-proxy:4180; | |
| proxy_set_header Host $host; | |
| proxy_pass_request_body off; | |
| proxy_set_header Content-Length ""; | |
| } | |
| location = /oauth2/callback { | |
| auth_request off; | |
| proxy_pass http://oauth2-proxy:4180; | |
| proxy_set_header Host $host; | |
| } | |
| location / { | |
| satisfy any; | |
| auth_request /oauth2/auth; | |
| error_page 401 = /oauth2/start?rd=$uri; | |
| allow 127.0.0.1; | |
| deny all; | |
| proxy_read_timeout 300; | |
| proxy_pass http://kibana:5601; | |
| } | |
| } | |
| } | |
| daemon off; | 
auth_requestディレクティブでOAuth2認証を有効にしています.あとの部分は読むとだいたいわかると思います.このnginx.confの内容については以下の記事が詳しいです (というかパクりました,ありがとうございます).
docker-compose.yml
| version: '2.1' | |
| services: | |
| kibana: | |
| image: 'docker.elastic.co/kibana/kibana-oss:6.1.0' | |
| elasticsearch: | |
| image: 'docker.elastic.co/elasticsearch/elasticsearch-oss:6.1.0' | |
| oauth2-proxy: | |
| image: 'a5huynh/oauth2_proxy:2.2' | |
| command: > | |
| '--http-address=0.0.0.0:4180' | |
| '--cookie-secure=true' | |
| '--cookie-expire=24h' | |
| '--cookie-httponly=true' | |
| '--cookie-domain=kibana.example.com' | |
| '--cookie-name=<cookie-name>' | |
| '--cookie-secret=<cookie-secret>' | |
| '--upstream=http://kibana:5601' | |
| '--email-domain=<email-domain>' | |
| '--client-id=<client-id>' | |
| '--client-secret=<client-secret>' | |
| nginx: | |
| image: 'nginx:1.13.5' | |
| links: | |
| - 'kibana' | |
| - 'oauth2-proxy' | |
| volumes: | |
| - './nginx.conf:/etc/nginx/nginx.conf' | |
| command: 'nginx' | |
| https-portal: | |
| image: 'steveltn/https-portal:1' | |
| ports: | |
| - '80:80' | |
| - '443:443' | |
| links: | |
| - 'nginx' | |
| restart: 'always' | |
| environment: | |
| DOMAINS: 'kibana.example.com -> http://nginx' | |
| STAGE: 'local' | 
<>で囲われた部分については適宜書き換える必要があります.
ここで利用されているhttps-portalはLet's Encryptを利用してSSL/TLS証明書の取得を自動化しつつSSL終端してくれるコンポーネントです.これ利用している理由はGoogleのOAuth2認証がリダイレクトしてくる時にhttpsを利用するからです.もしnginxの側でSSL/TLS化してる場合や,ELB等の上流でSSL終端している場合などは不要です.
なお,STAGE: 'local'と記述しておくとLet's Encryptは利用せずにオレオレ証明書を利用するモードになるのでローカルでの検証等で便利です.つまり本番で使ってはならない.本番運用時にはSTAGE: 'production'などと記述する必要があるでしょう (ドキュメントを参照のこと: https://github.com/SteveLTN/https-portal).
docker-copose upしてアクセスするとこんな感じで動きます (kibana.example.comをそのまま利用する場合はhosts等を適宜書き換えておく必要があります).
Googleのログインページが開き,適宜やっていくと
という感じでKibanaが開きます.便利便利.よかったですね.