LoginSignup
8
11

More than 3 years have passed since last update.

nginx でホストしたサイトに Cognito で OAuth2 認証をかける

Posted at

はじめに

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 のコンソールにログインします。

「ユーザープールの管理」をクリックします

cognito-00.jpg

「ユーザープールの作成」をクリックします

cognito-01.jpg

「属性」部分は用途に応じて適当に設定します

cognito-02.png

「ポリシー」でパスワード強度等を設定します

cognito-03.png

「MFAそして確認」では多要素認証について設定します

cognito-04.png

今回はMFAを無効にします。

「アプリクライアント」でアプリケーションを追加します

cognito-05.jpg

ここではトークンの有効期限を設定できます。

アプリの統合 / アプリクライアントの設定

cognito-06.jpg

「アプリの統合 / アプリクライアントの設定」で、コールバックURL、サインアウトURLを設定します。
* コールバックURLは、oauth2_proxy をホストしているURLを設定します。URLのパスは、/oauth2/callback です。
* コールバックURLは、https である必要があります。
* 「有効なIDプロバイダ」で、「Cognito User Pool」にチェックを入れます

アプリの統合 / ドメイン名

cognito-07.png

「アプリの統合 / ドメイン名」で、適当な値を設定します。

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 は、ユーザープールの「全般設定」で確認できます。

pool_id.jpg

※ 手元で試した環境では、設定ファイルの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;
    }


}

試してみる

認証をかけたサイトを開く

Sign_In.jpg

ログインのためのボタンが表示されます。クリックします。

ログイン画面で認証情報を入力する

login.jpg

Cognito のログイン画面が表示されるので、認証情報を入力します。

ログインが成功すると、認証をかけたサイトの内容が表示されます。

8
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
11