2010-11-29 17 views
24

共有クロスドメインログインシステムの実装方法、ベストプラクティスとセキュリティ上の予防措置に関心があります。 37Signalsに精通している場合は、普遍的な共有認証メカニズムを使用することに慣れているため、トップレベルのナビゲーションを別の製品に使用するとログインする必要はありません。同様の方法で何かを実装したいと思います。複数のドメイン間で共有ログインサービスを作成するにはどうすればよいですか?

私がオンラインで見つけた最も近いものは、Central Authentication ServiceにあるWikipediaのエントリと、Cross Domain Login - How to login a user automatically when transfered from one domain to anotherへの応答です。この場合、若干異なる場合があります。

私はセッションクッキーを検査して、そのプロセスで何をしているのか把握しています。最初は、各製品のリンクは「後藤」uristub、すなわちありますFireCookieとFirebugのでNET]タブを使用して

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

を、私は設定されているクッキーとリダイレクトを見ることができますよそのプロセスで発生します。セッション識別子が再作成され

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

、CSRFの目的のために最も可能性が高い:goto urlは302リダイレクトへを発射します。クッキーのデータだけでなく、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[��: 

߾」

エンコードは、コードブロックを壊しているおかげ。あなたの助けのために!

+0

OpenID、Facebook、OAuth、Googleなどのパッケージ化された共有ログインサービスはあなたのために機能しますか?または、あなた自身の共有ログインサービスが絶対に必要ですか? – Flipster

答えて

49

Qのキーは、「別の製品にトップレベルのナビゲーションを使用すると、後でログインする必要はありません」と書かれています。

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

異なるドメイン間でクッキーが共有できないため(サブドメイン以外のドメインだと思いますが、サブドメインについては言及していないようです)、site2.comへのリンクにいくつかの情報を渡す必要があり、あなたがどんなユーザーであるかを知ることができます。

まず、簡単な解決策を考えてみましょう。 いくつかのバックエンドDBにユーザーテーブルがあり、ユーザーにIDがあるとします。 ここで、ユーザーはsite1.comで認証され、DBからユーザー123であると仮定します。 最も簡単な解決策は、site2.com/url/whatever?myRealID=123 を呼び出して、このIDをsite2で確認し、これが実際に彼であることをユーザーに「信じる」ことです。

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

解決方法:ユーザーテーブルに一意の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がこのドメインによって認証されたユーザーのために、このリンクが当時サイトで作成されたことを証明するものです」と言って、タイムスタンプとGUIDとともにsite2.comに送信します。今すぐsite2.comがリンクを取得したとき、彼はそれが適切に署名されていることを確認することができます。そして、何人かの仲買人または元々のユーザが(時間やGUIDを変更する)何らかの方法でそれを変更しようとすると、署名は一致しません。 comはユーザーの認証を拒否します。

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

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

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

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

+1

共有キーの実装をさらに強化するには:共有ログインシステムの各ドメインの公開鍵/秘密鍵のペアを含むconfig変数を追加します。署名の検証方法がすべてのボックスで同じ場合は、署名を検証し、mcrypt()または同等のライブラリを使用して双方向で暗号化されたデータを転送して、検証署名の上にセキュリティを強化することもできますデータのチェックサム)。 –

+0

ナンス(バックエンドのセッションIDにリンクされている)だけを使用してみませんか?つまり、バックエンドのセッションIDにリンクされているトークンを作成するだけです(おそらく1〜2分の有効期限で、1回しか使用できません)。したがって、サイト2で使用すると、サーバーはセッションIDをデータベースから取得して消去できますトークンを取得してクッキーをブラウザに戻し、ブラウザにsite1と同じセッションを与えます。このアプローチにはどんな欠点がありますか? – mettjus

+0

少なくとも1つの相違点は、すべてのハッキング試行でDBに行かなければならないということです。それよりもコストがかかる場合は、データが正しく署名されていることを確認し、DBが実際に正しく署名された – epeleg

0

あなたが前後に送られているものを盗聴するCharlesのようなものを試したことがありますか?あなたのために、さらに物事を打破することができるかもしれません。

をuはおそらく、FlipScriptで述べたようにOAuth/OpenIDを歌うのがあなたのための方法かもしれませんか?

0

はJasig CAS http://www.jasig.org/casを見てみましょう。私はそれがあなたが望むことをするだろうと思う。オープンソースで、複数の認証ソースと複数のドメイン/言語を使用して認証するプラグインが数多くあります。

1

facebook/yahoo/gmail/openIDソリューションの使用をユーザーに許可するのはスタートですが、独自のソリューションを実装または使用するソリューションを徹底的に解決するわけではありません。

過去の実装を開発して管理していた(最終的にはSiteMinderに向かいましたが、実際の製品のコストを望まないと思っています)、Eyalは非常に良いアイデアを持っていますが、それに少し微調整を加える。

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

4

Global Network Auto-Loginソリューションを実装しようとすると、スタックオーバーフローが発生する可能性があります。
Kevin Montrose hereによる素晴らしい実装についての洞察力の高い記事があります。

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

0

なぜ使用しないのですか?この目的でIDを開きます。

OperIDがこの問題の最適な解決策になります。

+0

オープンIDは認証する良い方法ですが、それは問題を解決しませんつまり、あなたのOpen IDを使用してsiteA.comにログインする場合、上記の方法でもsiteB.comにログインしている状況を作成する必要があります。 ところで、認証できるようにするには一般的なソーシャルネットワークでは、gigya.com(私が最近まで働いていた場所)で提供されているソリューションを使用することもできますが、これは自分で処理しなければならないドメインを越える問題を解決しません。 – epeleg

0

.NET Passport(IE。Windows Live Id)のようなものを使用するか、Facebookが公開して閲覧できるAPIでFacebookが行った方法。

関連する問題