Discourse をご自身の Web アプリケーションのアイデンティティプロバイダーとして使用したいですか?素晴らしいですね!始めましょう。
DiscourseConnect プロバイダー設定の有効化
Discourse 管理サイト設定(/admin/site_settings)で、設定項目 enable discourse connect provider を有効にし、SSO ペイロードのハッシュ化に使用されるシークレット文字列を discourse connect provider secrets に追加します。
Web アプリケーションへの DiscourseConnect の実装:
-
ランダムな nonce を生成します。この値を
NONCEと呼びます。応答で返される nonce 値と検証できるように、一時的に保存します。 -
NONCEとRETURN_URL(Discourse が検証後にユーザーをリダイレクトする場所)を持つ新しいペイロードを作成します。ペイロードは次のような形式である必要があります:nonce=NONCE&return_sso_url=RETURN_URL。RETURN_URLのホストは、discourse connect provider secretsの設定時に使用したドメインパターンと一致する必要があります。 -
上記の生のペイロードを Base64 エンコードします。このペイロードを
BASE64_PAYLOADと呼びます。 -
上記の
BASE64_PAYLOADを URL エンコードします。このペイロードをURL_ENCODED_PAYLOADと呼びます。 -
sso プロバイダーシークレットをキーとして
BASE64_PAYLOADから HMAC-SHA256 シグネチャを生成し、そこから小文字の 16 進数文字列を作成します。このシグネチャをHEX_SIGNATUREと呼びます。
Discourse への認証リクエストの送信
ユーザーを DISCOURSE_ROOT_URL/session/sso_provider?sso=URL_ENCODED_PAYLOAD&sig=HEX_SIGNATURE にリダイレクトします。
Discourse からの応答の取得:
上記の手順が正しく実行されると、Discourse はログインしたユーザーを指定された RETURN_URL にリダイレクトします。クエリ文字列パラメーターとして sig と sso、およびいくつかのユーザー情報を受け取ります。次に、以下の手順に従います。
-
sso プロバイダーシークレットをキーとして
ssoの HMAC-SHA256 を計算します。 -
sigを 16 進数表現からバイトに変換します。 -
上記の 2 つの値が等しいことを確認します。
-
ssoを Base64 デコードします。埋め込まれたクエリ文字列が得られます。これにはnonceというキーが含まれており、その値は元々渡された nonce と一致する必要があります。これが一致することを確認し、システムから nonce を削除するようにしてください。 -
このクエリ文字列には多くのユーザー情報も含まれていることがわかります。必要に応じて使用してください。
これで完了です。これで、Web アプリケーションが Discourse を SSO プロバイダーとして使用するように設定できました!
その他のパラメーター、その他のオプション
nonce と return_sso_url に加えて、リクエストペイロードにはいくつかの追加のオプションパラメーターがあります。
-
prompt:prompt=noneの場合、SSO リクエストは「確認のみ」のリクエストとして扱われます。ブラウザ/デバイスがすでに Discourse にログインしている場合、Discourse は通常どおり認証情報を含む成功した SSO 応答を返します。ブラウザ/デバイスがまだログインしていない場合、Discourse はユーザーにログインを求めず、ユーザー情報を含むのではなく、代わりにfailed=trueパラメーターを含む SSO 応答を直ちに返します。これは、ログインダイアログを表示せずにユーザーがログインしているかどうかを確認するためのメカニズムを提供します。 -
logout:logout=trueの場合、SSO リクエストはログアウトリクエストになります。そのブラウザ/デバイスでユーザーが Discourse にログインしている場合、そのデバイスからログアウトされます。いずれの場合も、Discourse はssoやsigをクエリ文字列に追加せずに、直ちにreturn_sso_urlにリダイレクトします。 -
require_2fa:require_2fa=trueの場合、Discourse はリダイレクトバックの前にユーザーに二要素認証(2FA)の確認を要求します。応答ペイロードには、ユーザーが 2FA 検証を正常に完了した場合にconfirmed_2fa=trueが含まれるか、ユーザーが 2FA メソッドを何も設定していない場合にno_2fa_methods=trueが含まれます。
prompt=none と logout=true は相互に排他的です。同じリクエストで両方を提供することは意味がありません。
sso= ペイロードリファレンス
リクエストパラメーター:
nonce: (文字列、必須) 安全に生成されたランダムな文字列return_sso_url: (文字列、必須) 応答とともにリダイレクトバックする URLprompt: (文字列、オプション)noneの場合、ユーザーにログインを促さずに認証状態を問い合わせます。logout: (ブール値、デフォルトfalse)trueの場合、Discourse からユーザーをログアウトさせます。require_2fa: (ブール値、デフォルトfalse)trueの場合、リダイレクトバックの前にユーザーに二要素認証の確認を要求します。
結果パラメーター:
-
ログアウトリクエストへの応答には、
sso=ペイロードもシグネチャも含まれず、リクエストのプレーンなreturn_sso_urlへのリダイレクトのみが行われます。 -
ログインリクエストの結果ペイロードには、リクエストから反映された
nonceが常に含まれます。 -
結果ペイロードは、その他のリクエストパラメーターも反映します。この動作に頼らないでください。必ずしも意図されたものではなく、API の保証された側面ではありません。(例:なぜ
return_sso_urlパラメーターがreturn_sso_urlに送信されるペイロードにコピーされるのですか?) -
リクエストがユーザーの認証に失敗した場合、結果ペイロードには
failed=trueが含まれます。 -
リクエストがユーザー認証に成功した場合、結果ペイロードにはユーザーの資格情報/情報が含まれます:
external_id: (文字列) Discourse ユーザー IDusername: (文字列) ユーザー名/ハンドルname: (文字列) ユーザーの本名email: (文字列) メールアドレスavatar_url: (文字列) ユーザーがアップロードしたアバター画像の完全な CDN URLadmin: (ブール値) ユーザーが管理者であればtrue、そうでなければfalsemoderator: (ブール値) ユーザーがモデレーターであればtrue、そうでなければfalsegroups: (文字列) ユーザーが属するグループ名(名前順)のコンマ区切りリストprofile_background_url: (文字列) ユーザーのプロフィール背景画像の完全な CDN URLcard_background_url: (文字列) ユーザーのカード背景画像の完全な CDN URLconfirmed_2fa: (ブール値) ユーザーが 2FA 検証を完了した場合にtrue(require_2fa=trueが要求された場合にのみ存在します)no_2fa_methods: (ブール値) ユーザーが 2FA メソッドを設定していない場合にtrue(require_2fa=trueが要求された場合にのみ存在します)
name、avatar_url、profile_background_url、card_background_urlは、ユーザーがこれらを設定していない場合は省略されることがあります。(Discourse 内でnilの値を持つ要素は応答から除外されます。)
Discourse 公式の「Discourse をアイデンティティプロバイダーとして使用する」実装:
- Discourse SSO を使用してユーザーを認証する http プロキシ(管理者のみ): GitHub - discourse/discourse-auth-proxy: An http proxy that uses the DiscourseConnect protocol to authenticate users · GitHub (@sam 作成)
コミュニティ提供の「Discourse を SSO プロバイダーとして使用する」実装:
-
Discourse を SSO プロバイダーとして実装する PHP スクリプト: Discourse sso provider login · GitHub (@paxmanchris 作成)
-
Erlang:
https://github.com/reverendpaco/discourse-as-sso-erlang -
Node.js:
GitHub - edhemphill/passport-discourse: A Passport strategy for authenticating using a Discourse forum · GitHub
GitHub - ArmedGuy/discourse_sso_node: npm package for Discourse SSO login features. · GitHub -
ASP.NET Core(設定のみ必要):
GitHub - Biarity/DiscourseSso: Easy, configurable Discourse SSO: GET /auth/login -> recieve a JWT with user data · GitHub -
MediaWiki 拡張機能(PHP):
DiscourseSsoConsumer, a SSO extension for MediaWiki (@mdoggydog 作成)
