はじめに
Sphinx などで生成したフラットファイルを公開するのに、認証をかけたい場合、Basic認証などもありますが、公開先のユーザーが削除されたりするとパスワード変更や通知の手間が大変なので、OAuth2 認証をかけたい、といった状況があると思います。
そういった場合に、oauth2_proxyと nginx が使えることが、こちらのとても素晴らしいサイトYtaka Kato oauth2_proxy と Auth0 を用いた Nginx のお手軽 OAuth 化に紹介されています。
今回はこちらのサイトに紹介されている内容を、AWS Cognito を使って実施してみました。(Cognito部分以外は前述のページを参照いただいた方が良いかもしれません。。)備忘録としてのメモです。
サイトのSSL化
Cognito で認証をかけるには、コールバックURLが https である必要があります。まず nginx でホストしている、認証をかけたいサイトをSSL化する必要があります。
acme-tinyなどを使って、Let's Encrypt でサーバ証明書を取得し、Virtual Host を SSL化します。
server {
listen 443 ssl;
server_name your.domain.name;
ssl_certificate /path/to/signed.crt;
ssl_certificate_key /path/to/domain.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
ssl_session_cache shared:SSL:50m;
ssl_dhparam /path/to/server.dhparam;
ssl_prefer_server_ciphers on;
location / {
index index.html;
try_files $uri $uri/ =404;
alias /var/www/somedocument/;
}
}
oauth2_proxy のインストール
こちら を参考にして、バイナリをダウンロードします。go製なのでセットアップが簡単でいいですね。
今回は nginx と同じマシンにインストールしました。設定は後から行います。
systemdでサービス化するサンプルも、同じプロジェクトの contribで公開されています。
Cognito でユーザープールを作る
Cognito のコンソールにログインします。
「ユーザープールの管理」をクリックします
「ユーザープールの作成」をクリックします
「属性」部分は用途に応じて適当に設定します
「ポリシー」でパスワード強度等を設定します
「MFAそして確認」では多要素認証について設定します
今回はMFAを無効にします。
「アプリクライアント」でアプリケーションを追加します
ここではトークンの有効期限を設定できます。
アプリの統合 / アプリクライアントの設定
「アプリの統合 / アプリクライアントの設定」で、コールバックURL、サインアウトURLを設定します。
- コールバックURLは、oauth2_proxy をホストしているURLを設定します。URLのパスは、
/oauth2/callback
です。 - コールバックURLは、https である必要があります。
- 「有効なIDプロバイダ」で、「Cognito User Pool」にチェックを入れます
アプリの統合 / ドメイン名
「アプリの統合 / ドメイン名」で、適当な値を設定します。
Oauth2_proxy を Cognito 向けに構成する
こちらのチケットIntegrating oauth2_proxy with AWS Cognitoにサンプルの構成例が出ています。
こちらを参考に、下記のような構成で動作しました。
細かい設定パラメーターについては、OAuth2 Proxy の Configurationページに書かれています。
provider = "oidc"
client_id = "XXXXXXXXXXXXXXXXXXX"
client_secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
oidc-issuer-url = "https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_XXXXXXXXX"
redirect_url = "https://my.oauth2proxy.domain/oauth2/callback"
login-url = "https://tsh-rpa-support-100.auth.ap-northeast-1.amazoncognito.com/oauth2/authorize"
profile-rul = "https://tsh-rpa-support-100.auth.ap-northeast-1.amazoncognito.com/oauth2/userInfo"
redeem-url = "https://tsh-rpa-support-100.auth.ap-northeast-1.amazoncognito.com/oauth2/token"
scope = "openid"
cookie_secure = false
#upstream = "URL OF THE APP"
email_domains = [
"*"
]
cookie_secret = "secret"
http_address = "127.0.0.1:4180"
whitelist-domain = "tsh-rpa-support-100.auth.ap-northeast-1.amazoncognito.com"
oidc-issuer-url について
Cognito の Developer Guideに、Issuer (iss)
のフォーマットが書かれています。
Issuer (iss)
The iss claim has the following format:
https://cognito-idp.{region}.amazonaws.com/{userPoolId}.
For example, if you created a user pool in the us-east-1 region and its user pool ID is u123456, the ID token issued for users of your user pool have an iss claim value of
https://cognito-idp.us-east-1.amazonaws.com/u123456.
User Pool ID は、ユーザープールの「全般設定」で確認できます。
※ 手元で試した環境では、設定ファイルのoidc-issuer-url
が効かず、起動パラメーターとして指定しました。
/opt/oauth2_proxy/oauth2_proxy -config /etc/oauth2proxy.conf --oidc-issuer-url="https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_XXXXXXXXXXX
login-url, profile-rul, redeem-url の URL
このドメインは、「アプリの統合 / ドメイン名」で指定したものを使います。
redirect_url
「アプリの統合 / アプリクライアントの設定」で指定したコールバックURLと同じ物です。
(Oauth2_Proxy をホストしているURLを指定します。URLのパスは、/oauth2/callback
です)
サイトに OAuth2 認証を設定する
先ほど SSL化した Virtual Host に対して、OAuth2 認証を設定します。
nginx の auth_request を使うところがポイントのようです。
server {
listen 443 ssl;
server_name your.domain.name;
ssl_certificate /path/to/signed.crt;
ssl_certificate_key /path/to/domain.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
ssl_session_cache shared:SSL:50m;
ssl_dhparam /path/to/server.dhparam;
ssl_prefer_server_ciphers on;
location / {
index index.html;
try_files $uri $uri/ =404;
alias /var/www/somedocument/;
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
}
location /oauth2/ {
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Auth-Request-Redirect $request_uri;
# or, if you are handling multiple domains:
# proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
}
location = /oauth2/auth {
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
# nginx auth_request includes headers but not body
proxy_set_header Content-Length "";
proxy_pass_request_body off;
}
}
試してみる
認証をかけたサイトを開く
ログインのためのボタンが表示されます。クリックします。
ログイン画面で認証情報を入力する
Cognito のログイン画面が表示されるので、認証情報を入力します。
ログインが成功すると、認証をかけたサイトの内容が表示されます。