多くのユーザーが既にサインアップした後でSSOを追加する場合、どのように移行すればよいですか?

皆さん、こんにちは。

Discourseの全ユーザーをintercoin.appにインポートする適切な方法はありますか?ハッシュ化されたパスワードやソルトなどを含む全ユーザーを返すRESTエンドポイントのようなものはありますか?ハッシュアルゴリズムのGitHubへのリンクはどこですか?ユーザーがログインできるように、独自のハッシュアルゴリズムが機能しない場合に、入力されたパスワードとソルトで同じハッシュアルゴリズムを使用するようにコードを記述する必要があります。Discourseユーザーが後でSSOを有効にする場合(私たちのように)、番号2が関連していると思いますが、それを解決することは他のDiscourseユーザーにも役立つでしょう。

「いいね!」 2

興味深いアプローチですね。

user.rb では

  def confirm_password?(password)
    return false unless password_hash && salt
    self.password_hash == hash_password(password, salt)
  end

  def hash_password(password, salt)
    raise StandardError.new("password is too long") if password.size > User.max_password_length
    Pbkdf2.hash_password(password, salt, Rails.configuration.pbkdf2_iterations, Rails.configuration.pbkdf2_algorithm)
  end

そして、Pbkdf2 コードはここにあります: discourse/lib/pbkdf2.rb at 201228162c277b9833bb2988388553fdbfb39521 · discourse/discourse · GitHub

「いいね!」 2

素晴らしい!では、パスワードハッシュとソルトを含むすべてのユーザー情報を取得するために呼び出すHTTPエンドポイントは何ですか?

一般公開用には(ハッキングを容易にする理由がないため)ないと思いますが、どうすればよいですか?MySQLデータベースに接続しますか?Discourseプラグインを作成しますか?

「いいね!」 1

それらが基本的にあなたの選択肢です。

「いいね!」 1

データベーススキーマはどこかに文書化されていますか?

DockerのPostgreSQLデータベースに接続するにはどうすればよいですか?くだらない質問でしたらすみません。

「いいね!」 1

チームと話しましたが、彼らも同意しています。メールアドレスが与えられた場合に、ユーザーに関するJSON情報をエンドポイント経由で公開する、小規模なDiscourseプラグインを構築するために誰かに支払う準備ができています。

discourse/app/models/user.rb at main · discourse/discourse · GitHub には「password_hash」のソルトとユーザー名がありますが、メールアドレスはありません。それについては、user_email discourse/app/models/user_email.rb at main · discourse/discourse · GitHub を参照してください。

したがって、メールアドレスが与えられると、プラグインはメールアドレスでuser_emailテーブルを検索し、user_idを見つけてユーザー行を取得し、ソルトを含むすべての「安全な」フィールドを送信します。

追加のセキュリティのために、リクエストは共有シークレットを使用してHMACで署名できます。これはプラグインに提供できます。

これを誰か作ってくれませんか?メッセージを送るか、ここに返信して連絡方法を教えてください。おそらく単純なものです(いくつかのSELECTと、シークレットが設定されている場合のHMACのチェック)。JSONを読み取ります。

「いいね!」 1

既存の admin/users/list/active.json を使用し、ハッシュ化されたパスワードで応答を拡張するだけです。

また、既存のAPI認証メカニズムに従ってください。別の車輪を再発明しないでください。

「いいね!」 1

では、すべてのユーザーとそのソルトおよびパスワードをインポートする、一度限りの処理を行うということですね?

それは結構ですが、それでもプラグインが必要ですよね?ですから、Discourse の誰かがそれを作成してくれると素晴らしいのですが。

「いいね!」 1

エクスポートしたい情報を取得するには、data explorer plugin を使用することをお勧めします。新しいプラグインを作成するよりもはるかに簡単です。

「いいね!」 1

この設定値はどのように確認できますか?デフォルト値はいくらで、コードのどこかに記載されていますか? @RGJ

root@server:~# cd /var/discourse/
root@server:/var/discourse# ./launcher enter app
x86_64 arch detected.
root@server:/var/www/discourse# rails c
[1] pry(main)> Rails.configuration.pbkdf2_iterations
=> 64000
[2] pry(main)>

ありがとうございます。RGJさん、いくつか簡単な質問があります。

xorcistライブラリは、単に高速な文字列XORですよね? 'a’が’a’とXORされて0になる文字があった場合、その文字列はどうなりますか? 文字列はNULL終端ではないのですか?

私の目標はこれをPHPに移植することなので、何かお手伝いできること(PHPで再現する方法の情報など)があれば、非常に役立ちます。

また、この行は何をしていますか? ret.bytes.map { |b| (\"0\" + b.to_s(16))[-2..-1] }.join(\"\")

$u = hash_hmac('sha256', $password, $salt . pack('N', 1));
$ret = $u = hash_hmac('sha256', $password, $u);
for ($i=2; $i<$iterations; ++$i) {
  $u = hash_hmac('sha256', $password, $u);
  $ret = ($ret ^ $u);
}
// TODO: Rubyが最後の行で何をしているか調べる

これは近いですか? このPHPコードを修正してもらえますか?

これは組み込み関数です。

$hash = hash_pbkdf2('sha256', 'YourPassword', 'YourSalt', 64000, 64, false);

通常、ハッシュアルゴリズムはバイナリデータ上で動作し、結果は出力時に16進数またはBase64でエンコードされます。そのため、問題ありません。

「いいね!」 1

リチャードさん、本当にありがとうございます!ユーザーランドのPHPで実装する手間が省けて、大変助かりました!

はい!Discourseの全ユーザーを、パスフレーズハッシュとともに当社のプラットフォームにインポートするスクリプトを作成できました。

まもなく、Discourseフォーラムを持つ誰もが、イベント、ビデオ会議、メディアなどを追加できるようになり、Discourseは「ディスカッション」タブに配置されます。結果はhttps://intercoin.appで確認できます

基本的に、あらゆるDiscourseのインストールをFacebookのようなモダンなソーシャルネットワークに転換します。これらの機能には長年取り組んできましたが、DiscourseやWordPressとも緊密に統合したいと考えています。これにより、人々はWordPress、Discourse、Qbixを組み合わせて、コミュニティ全体をセルフホストできるようになります。

しかし、まだ2つの問題が残っています。

  1. Qbixでは、HTTPS接続の場合でも、少なくともsha1(password + userId)でクライアント側でパスワードをハッシュしてからサーバーに送信します。これは、サーバーやMITMがパスワードを決して保持せず、サイト間で再利用できないようにするためです。しかし、Discourseは単純にパスワードをサーバーに送信します。そのため、クライアント側でのハッシュを無効にする必要がありました。クライアント側でhash_pbkdf2のイテレーションの一部を実行し、残りをサーバー側で実行することは可能でしょうか?試してみましたが、一致しないようです。
php > $password = 'abc';
php > $salt = 'def';
php > $a = hash_pbkdf2('sha256', $password, $salt, 64000, 64, false);
php > $b = hash_pbkdf2('sha256', $password, $salt, 1, 64, false);
php > $c = hash_pbkdf2('sha256', $password, $b, 63999, 64, false);
php > echo $a;
9d7a21ae4113bea06d81e0c486f45ab778bb739f19f7a6a305d8401918a9d8a1
php > echo $c;
f42af6861ebcf8560b027276e0d02ad46502636045486057d81be7c4c4aa630e
  1. DiscourseをSSOプロバイダーとして使用し、当社のサイトをSSOプロバイダーとして使用しないことは可能でしょうか?そうすれば、Discourseフォーラムのホストは、ログインがまったく同じで、Discourse側で行われるため、Qbix機能で拡張する可能性が高くなります。Facebook、Google、その他何でも。Discourse ConnectがSSOプロバイダーとして当社のコンシューマーサイトに返す情報の種類に関するドキュメントはありますか?少なくとも、ダウンロードできる写真、名、姓、ユーザー名などの情報が含まれていますか?

ぶっちゃけ、DiscourseがHTTPS経由でパスワードを送信することが、現時点で最大のセキュリティ上の課題だとは思いません。

はい、可能です。標準のユーザーシリアライザーでほとんどの情報が取得できると思います。
それでも十分でない場合は、APIを使用してDiscourseからさらに情報を取得することもできます。

「いいね!」 2

「正直、DiscourseがHTTPS経由でパスワードを送信することが、現時点で最大のセキュリティ上の課題だとは思えません。」

かわいいですね。あなたのsha1を見て、md5で対抗します :slight_smile:

pbkdf2が実際に分割できない理由がわかりました…問題は最初の行です:

U1 = PRF(Password, Salt + INT_32_BE(i))
U2 = PRF(Password, U1)
⋮
Uc = PRF(Password, Uc−1)

しかし、分割する方法について何かアイデアはありますか?純粋なユーザーランドPHPライブラリを使えばいいと思います:pbkdf2/src/PBKDF2.php at master · Spomky-Labs/pbkdf2 · GitHub

Discourseには、パスワードをワイヤーに送信する前にソルト(userIdでOK)でハッシュ化することを推奨します。なぜだめなのでしょうか?現在データベースに保存しているものと互換性がなくなる必要はありません。JavaScriptで最初の100回のイテレーションを実行し、次に64000から10を引きます。いずれにせよカスタム実装(railsからコピーしたもの)なので、isHashedという変数を渡すだけで、それがtrueであれば「最後の」64K-10ステップのみを実行します。

ユーザーIDはログイン前に不明なため、それは機能しません…

10回のイテレーションは安全ではなく、63990回のイテレーションは64000回のイテレーションよりも安全ではありません。したがって、わずかではありますが、1つの安全な方法を、より安全でない2つの方法と多くの余分な複雑さに置き換えているようです。

そして、実際の利点は何ですか?

「いいね!」 1