web-dev-qa-db-ja.com

複数のドメインで共有ログインサービスを作成する方法

共有のクロスドメインログインシステムを実装する方法と、実行するベストプラクティスとセキュリティ対策に興味があります。 37Signalsに精通している場合は、共有ユニバーサル認証メカニズムを使用することに慣れているため、別の製品にトップレベルのナビゲーションを使用する場合に、後でログインする必要はありません。同様の方法で何かを実装したいと思います。

私がオンラインで見つけた最も近いものは、 Central Authentication Service のWikipediaエントリと Cross Domainへの応答ですログイン-あるドメインから別のドメインに移行したときにユーザーを自動的にログインする方法 。この場合は少し異なる場合があります。

その過程で彼らが何をしているかを把握するために、私は彼らのセッションCookieを検査しました。最初は、各製品リンクには「goto」uristubがあります。つまり、

https://MY_COMPANY.campfirenow.com/id/users/ [int_identifier]/goto

FireCookieとFirebugの[NET]タブを使用すると、設定されているCookieと、プロセスで発生するリダイレクトを確認できます。 goto urlは、302リダイレクトを起動します。

https://MY_COMPANY.basecamphq.com/login/authenticate?sig= [BASE64_ENCODED_AND_ENCRYPTED_DATA]

セッションIDは、CSRFの目的で再作成される可能性があります。 Cookie内の一部のデータとGETパラメーターsigは、base64_decodeを使用して部分的に復号化され、次のようになります。

// sig GET param
array(2) {
  [0]=>
���ף�:@marshal_with_utc_coercionT7�z��<k��kW"
  [1]=>
  string(18) "���k�<kn8�f���to��"
}

// _basecamp_session cookie session param
string(247) {
:_csrf_token"1Sj5D6jCwJKIxkZ6oroy7o/mYUqr4R5Ca34cOPNigqkw=:session_id"%060c0804a5d06dafd1c5b3349815d863"
flashIC:'ActionController::Flash::FlashHash{:
@used{: auth{"
              MY_COMPANY{:
                       user_idi�3
:identity_idi�W����������s�]��:�N[��:

߾�����」

エンコーディングがコードブロックを壊しています。ご協力いただきありがとうございます!

33
Corey Ballou

Qで重要なのは、「別の製品へのトップレベルナビゲーションを使用する場合に、後でログインする必要がないこと」を書くことです。

説明します:site1.comからsite2.comに移動して、site1.com経由でログインしたユーザーであることをsite2.comに通知します。

cookieは異なるドメイン(サブドメイン以外のドメインですが、サブドメインについて話しているのではないようです)間で共有できないため、リンクでバックエンドとの通信を可能にし、何を知っているかを示すリンクをsite2.comに渡す必要があります。あなたがいるユーザー。

単純なソリューションから始めて、それがもたらす問題のいくつかを解決するために私たちの方法を働かせましょう:バックエンドDBにユーザーテーブルがあり、ユーザーにIDがあるとします。ここで、ユーザーがsite1.comで認証され、DBのユーザー123であると想定します。最も単純な解決策は、site2.com/url/whatever?myRealID = 123を呼び出して、このIDを確認し、これが本当に彼であることをユーザーに「信じさせる」ことです。

問題:リンクを見るだれでも(サイトの有効なユーザーであっても)、myRealID = 123のリンクを作成するか、他の値を試すことができます。そして、site2.comはそのユーザーとして彼を受け入れます。

解決策:推測可能なIDを使用しないでください。ユーザーテーブルに一意のGUIDを追加し、ユーザー123のguidが8dc70780-15e5-11e0-ac64-0800200c9a66の場合、site2.com/urlを呼び出します。/whatever?myGuid = 8dc70780-15e5-11e0-ac64-0800200c9a66。

新しい問題:まあ、誰かがあなたのユーザーのGUID彼のGUIDをまだ推測されている可能性は非常に低いですそして、誰かが彼が永遠にそれを使うことができるguidを得るでしょう。

解決策:サーバーに保存されている秘密鍵を使用して、次のデータアイテム、現在のタイムスタンプ、宛先サイト(「site2.com」)などのGUIDを含む文字列に署名します。この署名は、「これはこのリンクが、このGUID to this domain by authentication to this domain)を持っているユーザー用にサイトによって作成された証拠であり、タイムスタンプとともにsite2.comに送信します。 GUID。これで、site2.comがリンクを取得すると、適切に署名されていることを確認できます。仲介者または元のユーザーが何らかの方法で変更した場合(時間またはGUIDを変更した場合)、署名は一致せず、 site2.comはユーザーの認証を拒否します。

最後の問題:リンクが仲介者によって傍受された場合、他のマシンからの場合でも、彼はまだ使用できます。

解決策:渡されたパラメーターにナンスを追加します。 nonceは単なる乱数であり、認証システムは、この番号による認証を2回以上許可しないようにする必要があります(したがって、N(umber)-ONCEという名前を付けます)。これは、site2.comにつながるsite1.comで作成する各リンクには、後で検証するためにバックエンドに保存する必要がある個別のナンスが必要であることを意味します。

このノンステーブルにレコードを永久に追加し続けたくないので、そのようなリンクは作成後の一定期間のみ有効であると判断するのが習慣です。したがって、この制限時間よりも古いnonceレコードを作成できます。

これがあなたが探しているアウトラインであるといいのですが。何かを見逃した可能性もありますが、これらは基本的なガイドラインであり、署名を使用してリンク内のデータの信頼性を証明し、ナンスを使用して仲介者の攻撃を防止します。また、可能であれば、これらのリンクにHTTPSを使用することをお勧めします。

エヤル

60
epeleg

Global Network Auto-Login ソリューションをスタックオーバーフローで実装してみてください。
Kevin Montroseによる素晴らしい実装に関する洞察に満ちた投稿があります here

Cookie、HTML5 localStorage 、Javascript、Iframe、および多くのセキュリティチェックが必要ですが、それだけの価値があると思います。

5
systempuntoout

Facebook/yahoo/gmail/openIDソリューションを使用するオプションをユーザーに許可することは最初から始まりますが、独自のソリューションを実装または使用するソリューションを完全に解決するわけではありません。

過去に実装を開発して管理したことがある(私たちは最終的にSiteMinderに移行しましたが、実際の製品のコストは望んでいないと思います)、Eyalは非常に優れたアイデアを持っていると思いますが、少し微調整します。

認証時に、ランダムなコード(GUIDの値である可能性がありますが、ユーザーごとに静的ではありません)を生成し、ユーザーIDとともにトランザクションテーブルに格納します。このコードには最大存続期間(その期間の安全値を判断する必要があります)このコードは、理想的にはユーザー名でハッシュされるか、暗号化されてURLの一部として送信されます。

1
E Oslick

Jasig CAS http://www.jasig.org/cas をご覧ください。私はそれがあなたが望むことをすると思います。これはオープンソースであり、複数のドメイン/言語から複数の認証ソースを使用して認証できるようにするためのプラグインがいくつかあります。

0
ehudokai

Charles のようなものをやり取りして、送受信されているものを嗅ぎましたか?それはあなたのために物事をさらに分解することができるかもしれません。

FlipScript で述べたように、おそらくOAuth/OpenIDを使用するのが良い方法でしょうか?

0
Chris Kimpton

.NET Passport(IE。Windows Live Id)のようなものを使用するか、FacebookがAPIを使用してこれを実行した方法を公開します。

0