前回はStreamlitとNginxを連携させる構成を作りました。
今回は、このシステムにOAuth2認証を付け加えたいと思います。
OAuth2認証はGoogleのサービスを利用します。
環境
Windows 10 Pro
Docker Desktop 4.1.1
Visual Studio Code 1.62.2 + Docker extension
Googleの設定
Google Could Platformにログインし、新しいプロジェクトを作成します。
プロジェクト名は任意の名前を入れます。ここではStreamlitProxyとします。
作成をクリックします。
プロジェクトが作成されたら、そのプロジェクトを選択し、「APIとサービス」からOAuth同意画面を選択します。
OAuth同意画面では、Google Workspaceユーザーでない場合には外部しか選択できないので、外部を選択して、作成をクリックします。
アプリ名、その他必要情報を入力し、保存して次へをクリックします。
スコープ、テストユーザーは何も入力せずに、保存して次へをクリックします。
次に認証情報ページに移動します。
認証情報を作成からOAuthクライアントIDを選択します。
アプリケーションの種類はウエブアプリケーションを選択し、名前はデフォルトのままで大丈夫です。
URIにはhttp://localhost/oauth2/callbackと入力し、作成ボタンをクリックします。
するとクライアントIDとクライアントシークレットが表示されます。
後に使うので、これをメモしておきます(実際には何度でも見れるので、メモの必要はありません)。
以上でGoogle側の設定は完了です。
OAuth2 Proxyの設定
次に、認証を行うプログラムの設定をします。認証にはOAuth2 Proxyというプログラムを利用します。
以下の設定を前回作成したdocker-compose.ymlファイルに追加します。
authproxy:
image: quay.io/oauth2-proxy/oauth2-proxy:latest
networks:
shared-nw:
ports:
- "4180:4180"
command: --cookie-secure=false --upstream="http://0.0.0.0:80" --http-address="0.0.0.0:4180" --redirect-url="http://localhost/oauth2/callback" --email-domain="*"
environment:
OAUTH2_PROXY_COOKIE_SECRET: <クッキーシークレットをここにコピー>
OAUTH2_PROXY_CLIENT_ID: <クライアントIDをここにコピー>
OAUTH2_PROXY_CLIENT_SECRET: <クライアントシークレットをここにコピー>
OAUTH2_PROXY_COOKIE_EXPIRE: 30m
クライアントIDとクライアントシークレットはGoogleで取得したものをそのままコピーします。
クッキーシークレットはこちらのサイトに書かれている方法のどれかを使って作ります。
ここでは、Powershellを使ってやってみます。
以下のコードをVSCodeのTeminalで実行します。
Add-Type -AssemblyName System.Web
[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes([System.Web.Security.Membership]::GeneratePassword(32,4))).Replace("+","-").Replace("/","_")
生成された文字列をコピーして、docker-compose.ymlの該当箇所に貼り付けます。
その他の設定項目としては、OAUTH2_PROXY_COOKIE_EXPIREはセッションが切れる時間です。
ここでは30mということで、30分で再認証が必要になる設定にしてあります。
docker-compose.ymlファイルは全体で以下のようになります。
version: '3.8'
services:
streamlit:
build:
context: ./Streamlit
networks:
shared-nw:
ports:
- 8501:8501
command: hello
nginx:
build:
context: ./Nginx
ports:
- 80:80
networks:
shared-nw:
authproxy:
image: quay.io/oauth2-proxy/oauth2-proxy:latest
networks:
shared-nw:
ports:
- "4180:4180"
command: --cookie-secure=false --upstream="http://0.0.0.0:80" --http-address="0.0.0.0:4180" --redirect-url="http://localhost/oauth2/callback" --email-domain="*"
environment:
OAUTH2_PROXY_COOKIE_SECRET: bl1mWUtRUl9CZjE4cFVjOjJrWTokSUNlazgkcCElSno=
OAUTH2_PROXY_CLIENT_ID: <クライアントIDをここにコピー>
OAUTH2_PROXY_CLIENT_SECRET: <クライアントシークレットをここにコピー>
OAUTH2_PROXY_COOKIE_EXPIRE: 30m
networks:
shared-nw:
driver: bridge
Nginxの設定
最後にNginxの設定です。
OAuth2 Proxyへの転送設定を追加して、以下のようになります。
events {
worker_connections 16;
}
http {
server {
listen 80;
server_name localhost;
location /oauth2/ {
proxy_pass http://authproxy: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;
}
location = /oauth2/auth {
proxy_pass http://authproxy:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header Content-Length "";
proxy_pass_request_body off;
}
location / {
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
proxy_pass http://streamlit:8501/;
}
location ^~ /static {
proxy_pass http://streamlit:8501/static/;
}
location ^~ /healthz {
proxy_pass http://streamlit:8501/healthz;
}
location ^~ /vendor {
proxy_pass http://streamlit:8501/vendor;
}
location /stream {
proxy_pass http://streamlit:8501/stream;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
}
}
コンテナを起動
では、コンテナを起動します。
docker-compose.ymlファイルを選択、右クリックし、Compose Upを選択します。
コンテナが起動したら、ブラウザでhttp://localhostにアクセスします。
OAuth2 Proxyの画面が出てくるので、Sign in with Googleボタンをクリックします。
Googleのサイトに飛びますので、アカウントを選択します。
Streamlitのデモ画面が見れれば完成です。