AWS App RunnerでホストしたNginxをCognito認証で保護する

AWS App RunnnerでWEBサーバーをホスティングしたい。ついでにCognitoの認証を使いたいということで調べてみてます。

以下のIssueで関連する内容が提案されているので、どこかで対応されるかもしれません。

github.com

利用技術

OAuth2 Proxyを使うと簡単に実現可能でした。

oauth2-proxy.github.io

以下の左の図にApp Runnerが追加されたイメージです。

サンプルのコンテナは以下に公開しています。

github.com

事前設定

Cognitoの設定確認

この記事で紹介するコンテナを動かすにはCognitoのユーザプールが必要です。

Cognitoの設定内容はここでは書かないですがOIDCの設定がしてあれば基本的には動くと思います。

OAuth2 Proxyとの連携のために以下の情報が必要なので準備します。

  • ユーザプールID
  • アプリケーションクライアントID
  • アプリケーションクライアントシークレット
ユーザプールIDの確認

ユーザプールのIDは色々なところから確認できます。例えば以下のようなユーザープールの一覧から確認可能です。

アプリケーションクライアントの情報確認

以下の画面にある クライアントIDクライアントシークレット を取得します。

ローカルで動作確認

まずはローカルでCognito認証するNginxコンテナを起動してみます。

リポジトリのクローン

上にも書いた以下のリポジトリを使います。

github.com

git clone https://github.com/yomon8/apprunner-cognito-nginx-sample-container.git
cd apprunner-cognito-nginx-sample-container/

設定ファイル修正

Oauth2 Proxyの設定をサンプルファイルから作成します。

cp -ai ./config/oauth2proxy.conf{.sample,}

上記のCognito画面で確認した情報を元に ./config/oauth2proxy.conf の以下の3つの設定を修正します。

# AWS_REGIONを置換
# xxxxxをCognito User Pool IDで置換
oidc_issuer_url = "https://cognito-idp.ap-northeast-1.amazonaws.com/xxxxx" 

# CognitoのApplication Client ID と Secretを設定します。
client_id = "....."
client_secret = "....."

コンテナのビルドと起動

ローカルホストでコンテナをビルドして起動してみます。

DOCKER_BUILDKIT=1 docker build -t cognito-nginx-sample . && docker run -p 80:80 cognito-nginx-sample  

起動してみました。

動作確認

早速動作確認してみます。

http://{DOCKER_HOST} にアクセスしてみると、以下のようにOAuth2 Proxyの画面が表示されます。Sign in with OpenID Connect をクリックします。

そうすると、Cognitoの認証画面に遷移します。

ユーザとパスワードを入れてCognitoの認証が通ると、Nginxのトップ画面が表示されます。

App Runnnerで動作確認

今度はAppRunner上で上記のコンテナを動かしてみます。

App Runnerの設定

App RunnerはGitHub上のソースコードやECR上にPushしたコンテナをソースとしてアプリケーションを起動します。

ECRの作成し、AppRunner側もほとんど設定すること無いのですが、以下のように設定しました。

ポートがデフォルトで 8080 となっているのですが、今回は 80 にしているので注意してください。

コンテナのビルド

./config/oauth2proxy.conf のコメントアウトされている redirect_url にApp Runnerのデフォルトドメインを設定します。

(またはDNSに登録したALIASやCレコード)

# xxxxxx.ap-northeast-1.awsapprunner.comはデフォルトドメインやDNSに登録したALIASやCNAMEなどを指定
redirect_url = "https://xxxxxx.ap-northeast-1.awsapprunner.com/oauth2/callback"

設定したらApp Runnderで指定したECRにイメージをPushします。

Cognitoの設定

Cognitoの設定にある、許可されたコールバックURLに上記で redirect_url に設定したURLを追加します。

動作確認

App Runnerのデフォルトドメインなら https://xxxx.ap-northeast-1.awsapprunner.com のようなドメインにアクセスすることでローカルと同じように認証のフローを確認できるはずです。

詰まったところ

Cognito認証後にNginxで502 Bad Gatewayが出る

認証はできているはずなのに、Nginxの以下のエラーが出て詰まりました。

ログを見るとOAuth2 Proxyのログに以下のように出力されます。

[2022/11/15 02:02:29] [session_store.go:163] WARNING: Multiple cookies are required for this session as it exceeds the 4kb cookie limit. Please use server side session storage (eg. Redis) instead.

以下のパラメータをOAuth2 Proxyの設定に追加することで回避できました。

session_cookie_minimal = true