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が開きます.便利便利.よかったですね.