自宅鯖でstable-diffusion-webuiを建てました。自分だけ使うのはもったいないけど世界中に公開するのは怖い・・・と思ったので身内Discordサーバーに入っている人だけがアクセスできるようにしました。今回はその手順を紹介します。
ざっくりやること#
(以下を見て「わかった!」って方はもう記事を見なくてもいいかもです)
Cloudflare Workers + DiscordのOauthを使ってOpenID Connectに使える認証サーバを構築し、それをCloudflare Zero Trustの認証プロバイダに登録する。Cloudflare Accessで認証したユーザのClaimを確認し、Discordサーバーに入っているか判定する。
本編#
前提#
- Cloudflareに登録済みなこと
- wrangler(cloudflareのcli)をセットアップしていること。セットアップ方法は公式サイトに解説があります。
1. Discord Developer Portalでアプリを作る#
まずはDiscord Developer Portalにアクセスして認証に使う用のApplicationsを作ります。「OAuth2」のページの「Client information」にある「Client ID」と「Client Secret」をメモしておきます。
2. Cloudflare Workersで認証サーバを構築#
自分で作ってもいいですが既に以下の実装を公開している方がいるのでそれを使います。
Erisa/discord-oidc-worker: Sign into Discord on Cloudflare Access, powered by Cloudflare Workers!
まずはgit clone
などを使いリポジトリをダウンロードします。
git clone https://github.com/Erisa/discord-oidc-worker
discord-oidc-worker
をセットアップしていきす。
セットアップ方法はGithubのREADMEに書いてありますがここでも解説します。
まずはnpmを使って依存関係をダウンロードします。
cd discord-oidc-worker
npm install
Cloudflare Workers KVを用意します。セットアップ方法は二種類あります。wranglerを使った方法とCloudflareのWebコンソールからぽちぽちやる方法です。wranglerの方が簡単なのでこちらを紹介します。
以下のコマンドでcloudflare workers KVを作成します。このKVはJSON Web Key(JWK)の保管に使います。
wranglerのバージョンが3.60.0以上であればkv:namespace
ではなくkv namespace
に読み替えてください。
npx wrangler kv:namespace create "discord_oidc_keys"
成功すると以下のような出力が出ると思います。
🌀 Creating namespace with title "worker-discord_oidc_keys"
✨ Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "discord_oidc_keys", id = "..." }
これの{ binding = "discord_oidc_keys", ...}
のbinding
をKV
に変更してwrangler.tomlにコピペします。
wrangler.tomlは以下のようになります。
name = "discord-oidc"
main = "worker.js"
compatibility_date = "2022-12-24"
kv_namespaces = [
{ binding = "KV", id = "..." },
]
次はconfig.sample.jsonをもとにconfig.jsonを作成します。
cp config.sample.json config.json
config.jsonを編集します。1でメモしたclient idとclient secretを使います。以下の通り書き換えてください。
{
"clientId": "YOUR_DISCORD_CLIENT_ID",
"clientSecret": "YOUR_DISCORD_CLIENT_SECRET",
"redirectURL": "https://YOUR_CLOUDFLARE_USER_NAME.cloudflareaccess.com/cdn-cgi/access/callback",
"serversToCheckRolesFor": ["YOUR_DISCORD_SERVER_ID"]
}
YOUR_DISCORD_CLIENT_ID
を実際のdiscordのclient idに書き換えるYOUR_DISCORD_CLIENT_SECRET
を実際のdiscordのclient secretに書き換えるYOUR_CLOUDFLARE_USER_NAME
を実際のcloudflareのユーザネームに書き換えるYOUR_DISCORD_SERVER_ID
をwebサイトにアクセスできるユーザーの入っているDiscordサーバーに書き換える(複数登録できます)
最後にデプロイします
npx wrangler publish
wranglerのバージョンが新しければ以下を実行します
npx wrangler deploy
3. Cloudflare Zero Trustを設定する#
先ほどたてたCloudflare WorkersをCloudflare Zero Trustの認証プロバイダに登録します。
「Settings」の「Authentication」に行き、「Login Methods」の項目の「Add New」をクリックして「Add OpenID Connect」ページに移動します。
フォームの項目を以下の通りに埋めます。
- Name: 自由。好きな名前を設定してください
- App ID: DiscordのClient ID
- Client secret: DiscordのClient secret
- Auth URL:
https://discord-oidc.YOUR_CLOUDFLARE_USER_NAME.workers.dev/authorize/guilds
- Token URL:
https://discord-oidc.YOUR_CLOUDFLARE_USER_NAME.workers.dev/token
- Certificate URL:
https://discord-oidc.YOUR_CLOUDFLARE_USER_NAME.workers.dev/jwks.json
- Proof Key for Code Exchange (PKCE): オンにする
- Email claim: 入力不要
OIDC Claimsは以下のように設定します
- id
- username
- discriminator
- guilds
以上を記入したら「Test」を押して実際に試してみるとよいでしょう。よさそうであれば「Save」を押して保存してください。
4. Cloudflare Accessを設定する#
3で作った認証をCloudflare Accessで使う設定をします。
Cloudflare Accessのページに行き、「Add an application」ボタンでアプリを作ります。
「Self Hosted」を選択します。
Application Configurationでアクセスを制限したいアプリのドメインを設定します。
- Session Durationはセッションが有効な期間を設定します
Identity ProvidersはOpenID Connectのみに設定します。
「Next」を押してPoliciesの設定へ進みます。
Configure Rulesを設定します。
Includeに以下を追加します
- OIDC Claimsを選択
- 「Claim name」に「guilds」を入力する
- 「Claim value」にDiscordのサーバーIDを入力
「Save Policy」を押して保存すれば設定完了。対象のドメインに移動して以下のような画面になっていれば成功しています。ログインして動作確認してみてください。
まとめ#
予想以上に簡単にできてよかったです。discord-oidc-workerはサーバだけでなくユーザ自身での認証もできるのでそちらも使うことがあるかもしれません。