SUPER-G.EEK.JP

twitter: @hum_op_dev
github: ophum

dexidp/dexのconnectorを実装してdiscord OAuth2で認証できるようにした

目次

dexidp/dexを利用することで OIDC に対応していない認証サーバーで OIDC できるようになります。

dex が OIDC のリクエストを受け取り connector を介して OAuth2 や LDAP などで認証します。

背景

connector には主要な ID Provider が実装されていますが Discord は実装されていないため oauth connector を利用することで discord oauth2 で認証することができます。 しかし、今回は、ある Discord サーバー(API 上では guild となっていた)に所属しているメンバーだけ認可したかったので、単に oauth connector を使うだけではこの要件を満たせませんでした。

そこで、oauth2 で認証して サーバー ID をチェックする discord-connector を実装しました。

connector の実装について

CallbackConnectorConnectorConfig のインターフェースを実装し登録することで connector を追加できます。 CallbackConnector は Discord OAuth2 とやり取りする実装をします。 Discord OAuth2 の認証 URL を返したり callback で認証されたら、Discord API で Guild メンバー情報やユーザー情報を取得し dex に返します。

ConnectorConfig は discordConnector の実装を返します。

class図

この ConnectorConfig を実装したdiscord.Configを server/server.go の ConnectorsConfig に登録することで、利用できるようになります。

https://github.com/dexidp/dex/blob/v2.39.1/server/server.go#L576

1var ConnectorsConfig = map[string]func() ConnectorConfig{
2	"keystone":        func() ConnectorConfig { return new(keystone.Config) },
3    ...
4    "discord": func() ConnectorConfig { return new(discord.Config) },
5}

実装 https://github.com/dexidp/dex/compare/master…ophum:dex:master

以下のように設定ファイルに記述することで利用できます。 guildID には Discord のサーバー ID を文字列で記述します。

1connectors:
2  - type: discord
3    id: discord
4    name: discord
5    config:
6      clientID: "discord client id..."
7      clientSecret: "discord client secret..."
8      redirectURI: https://localhost/dex/callback
9      guildID: ""

処理の流れは以下のようになってます。(適当に描いたので間違ってるとことあるかもしれないけど雰囲気)

シーケンス図