次のケースがあります: Website1 - php Website2 - ASP.Net Website3 - jsp Web サイトは相互に依存しているため、SINGLE SIGN ON を実装する必要があります。認証要求で取得できる単一の Cookie を作成する方法はありますか? ユーザーがいずれかの Web サイトにサインインすると、リダイレクト後にサインイン状態になるために、他の両方の Web サイトで読み取りおよび復号化できる Cookie が保存されますか? 同じデータベースと同じテーブル「shared.Users」を使用して、ユーザーの資格情報を保存しています。ここで何か助けはありますか?ありがとう
3 に答える
簡単な答え: はい。
より長い答え:
a) サーバーが同じドメイン上にある場合 (異なるサブドメインである可能性がありますが、同じルート ドメインである必要があります)、それらは両方とも同じ Cookie を読み取ることができます。サインオン サーバーはセッション ID を使用して Cookie を作成し、2 番目の Web サイトへの訪問者は Cookie を読み取ってサーバーに渡し、サーバーはサインオン サーバーへのバックエンド呼び出しを実行してセッション/ユーザーの詳細を取得し、ユーザーをサインオンさせます。
b) サーバーが異なるドメインにある場合、2 つのオプションがあります。1 つは、セッション ID を文字列として 2 番目のサーバーに渡すことです (醜い)。しかし、より良い (そしてより複雑な) のは、一連の隠しフレームです。(これを機能させるには、IE で P3P が必要です。他のブラウザーは問題ありません)。基本的に、隠しフレームはサインオン ドメインから読み込まれ、セッション ID を取得するために読み取り/操作できます。少しジャグリングですが、マップを作成するとうまく機能します。
編集:シングルサインオンオプション(詳細)
「A」と「B」と呼ぶ 2 つのサーバーがあります。
"A" は認証/ログオン システムを保持し、"B" は "A" にサインオンするときにサインオンするサーバーです。
これは、2 つのサーバーがまったく別のページを提供している場合、または一方が別のサーバー内の iFrame である場合に機能します。異なるプラットフォーム間でも動作します
最初に注意すること: サーバー「A」はサーバー「B」と情報を共有する必要があります。状況に応じて、これを行う 2 つの方法があります。最初のオプションは、両方が同じデータベースを共有し、そこにデータを保存することです。もう 1 つは、サーバーが互いに「対話」することです。後者を使用する場合は、CURL を使用してチェックサムを追加し、HTTP 呼び出しに特定のヘッダーを追加します。 - これにより、十分に安全になるはずです (誰もコードを見ない限り)。両者が同じデータ センターにない場合は、両者間に SSL 通信を追加する必要がありますが、ユーザーはそれらの呼び出しを確認できません。データベース (異なるプラットフォーム) を共有することはないと思われるので、サーバーが相互に通信できるようにする必要があります。
サーバー「A」で何が起こるか
"A" はページを配信し、セッション "X" を提供し、"Y" を Cookie に保存します。
ユーザーが使用しているサーバーに関係なく、ユーザーは "A" に送信されてログオンする必要があります。これは、「A」に「投稿」するすべてのページにログオン フォームを配置するか、「A」から配信されるログオン フォームをポップするポップアップ ウィンドウを実行するか、「A」から配信されるページにリダイレクトすることによって実行できます。(最後の 2 つは Facebook のやり方です。)
"A" は、ログインしているユーザーとセッション "X" を関連付けるユーザーに署名します。
ユーザーがサーバー「A」から提供されたページにアクセスすると、Cookie「X」を読み取ることができ、何が起こっているかを知ることができるため、すべてがうまくいきます。したがって、問題はサーバー「B」(または「C」または「D」など - これは拡張可能) です。
サーバー「B」で何が起こるか
ユーザーがサーバー「B」からページにアクセスすると、「A」から Cookie を読み取ることができません。簡単なオプションと複雑なオプションがあります
シンプル: サーバー "A" によって作成されたページからサーバー "B" へのすべてのリンクは、SessionID をパラメーターとして追加します。次に、サーバー「B」はサーバー「A」と通信して、セッションの詳細を取得します。これは、ユーザーが常にサーバー "A" からサーバー "B" に移動し、サーバー "B" に直接到達しない場合 (たとえば、Google などを介して) に最適です。実際には、これは優れたオプションではありません。
複雑: イベントのシーケンスは次のとおりです。
B はセッション「Y」をユーザーに割り当て、それを Cookie に保存します。
B は、「非表示」の iFrame を含む Web ページを配信します。非表示の iFrame の src は「A」によって配信されるページになり、セッション「Y」を GET パラメータとして呼び出しに追加します。
iFrame は、セッション "X" (Cookie を介して) およびセッション "Y" (GET パラメーターを介して) にアクセスできます。
(ゆっくり読んでください:) iFrame はサーバー "A" に、ユーザーがセッション "Y" を持っていることをサーバー "B" から聞いた場合、セッション "X" の場合と同じ資格情報を "B" に提供することを伝えます。 「Y」は「X」と同じで、2 つをリンクします。
(トリッキーな部分について) リンクが確立されると、サーバー "B" はサーバー "A" に接続し、「私はセッション "Y" です。この人ですか?」と言う必要があります。
ログオン?'。サーバー "A" は "X" を "Y" に一致させ、「はい、ここにユーザーの詳細があります」と言います。
もちろん、それほど単純ではありません...:
このアプローチの問題点は、「B」が配信する最初のページで、ユーザーがログオンしていないと見なされることです。(サーバー "A" は、iFrame が通信するまで "X" と "Y" をリンクしていないため、サーバー "B" がサーバー "A" に "Y" を知っていますか? と尋ねると、答えは "いいえ" になります。 )したがって、サーバー「A」を監視して、サーバー「B」にログオンしていることを知らせる必要があります。これはいくつかの方法で行うことができます。
サーバー "B" が Cookie を含むページを配信したことがない場合 (つまり、セッション "Y" が新しい)、またはサーバー "B" がサーバー "A" にクエリを実行し、サーバー "A" がセッション "Y" について聞いたことがないという応答をした場合、次に、非表示の iFrame を含む空白の「リダイレクト ページ」を配信し、しばらくしてから再試行すると、サーバー「A」は「Y」が誰であるかを認識し、彼がログインしているかどうかを確認できます。別の方法として、(ログオンしていない) ページ全体を配信し、サーバー "B" を常に呼び出してサーバー "A" が "Y" が誰であるかを認識しているかどうかを確認する JavaScript を使用します。応答を取得します。【注1】
この「サーバー "B" がサーバー "A" に連絡する」というトリックを繰り返して、"B" によって配信される各ページをトリックできます (これは、アプリが Facebook に接続する方法であり、ページごとに facebook 呼び出しを使用して読み込みます)。ただし、独自のサーバー。
または、サーバー「B」でセッション「Y」を個別に追跡し、サーバー「A」がセッション「X」に関連付けられている(したがってセッション「Y」に関連付けられている)ユーザーに連絡するまで、ユーザーがログインしていると想定できます。 ) がログアウトした場合、ユーザーをセッション "Y" からもログアウトします。
また、アクティビティを共有するために「サーバー間」呼び出しを使用することもできます (たとえば、「"X" に関連付けられたユーザーが実績を取得し、ローカル キャッシュを更新しました」、または「"Y" に関連付けられたユーザーがログアウトしました - ログ "X" をログアウトします」また')。また、これを Javascript 呼び出しでバックアップするので、2 つのタブで 2 つのページを表示している場合、1 つはサーバー "A" からのものです。
サーバー「B」から一度、一方からログアウトすると、Javascript呼び出しが定期的にチェックして、もう一方からログアウトします。
それで、セキュリティ?
「X」と「Y」はどちらも公開文字列です。これは、「Y」を盗んだ場合、「X」になりすますことができることを意味します。実際には、これは通常のセッション キー「X」を盗むことと変わりませんが、スプーフィングを防ぐためにさらに多くのことができます。「A」への iFrame 呼び出しは、正確に同じ IP、ユーザー エージェント、およびリファラー [注 2] から送信され、iFrame 呼び出しは「B」からの要求とほぼ同時に送信される必要があることがわかっています (give or take network 30 秒待ちます)。いずれかが一致しない場合は、セッション「Y」を破棄し、新しいセッション「Y」を作成して、「セッション「Y」は「X」と同じ」のプロセスを最初からやり直します。
次はどこ?
これには多くのバリエーションがあり、必要な正確なフローを得るために微調整が必要になる場合があります。同じシステムを使用して複数のアプリケーションにログインすることもできます (たとえば、Wordpress、SMF、およびカスタム ゲームがすべてデータを共有しているため、アプリケーションが異なるサーバー上にある場合でも、1 つにログオンし、別のゲームからログアウトします。ドメインを共有するので、Cookie を共有できるので少し楽になりますが、セッションを共有しないので、これに頼っています)。しかし、エンド ユーザーとしては、「リダイレクト ページ」または一時的な「ログオンしていない」ことを除けば、気付かないはずです。
もう 1 つのバリエーションとして、サーバー「A」は、サーバー「B」にページをロードする非表示の iFrame もロードできます。同じ種類のコミュニケーションですが、逆です。ユーザーは "A" にアクセスしないとログインできないため、ユーザーがログオンする前に iFrame は "X" と "Y" をリンクします。これは避けられません。したがって、ユーザーがサーバー「B」からページにアクセスすると、「X」と「Y」がリンクされ、ログオンしているかどうかがすぐにわかります。ただし、ポーリングはまだ必要なので、簡単にはなりません。
ノート:
注 1: javascript オプションを使用する場合は注意してください。私が作成したシステムの 1 つがビジー状態になり、サーバーが処理できなくなりました (これは 5 つのサーバーに分散していました)。JavaScript は応答を取得しませんでしたが、試行を続け、これが負荷に追加されました。これは、server->server 通信も通過できず、すべての Apache ソケットが使用されたため、すぐにシステム全体がメルトダウンしたことを意味します。Javascript はポーリングとポーリングを続け、システムがシャットダウンされた後も (もちろん) ブラウザは動作し続けました。古い呼び出し URL をブラックホール化し、別の URL に応答するように呼び出しを更新し、何らかの方法ですべてのユーザーのブラウザーに新しい Javascript を取得させて、それらが機能するようにしなければなりませんでした。したがって、ポーリング ルートを使用する場合は、このシナリオを計画してください。
注 2: 通常、これらは簡単に変更/スプーフィングされるため、ユーザーを検証するためにこれらに完全に依存するべきではありません。ただし、この場合、それらはまったく同じである必要があり、ユーザーが何か面白いことをしようとしていないことを確認するのに最適です。
注 3: これはシングル サインオン ソリューションの提案であり、そのバリエーションはいくつかのサイトで実装されています。各方法のさまざまなメリット、サーバー負荷、落とし穴、潜在的なセキュリティ ホールなどについての議論を求めているわけではありません。実装する際に検討する必要があります。途中でいくつかの落とし穴を見つけます。
はい、可能です。3つのWebサイトが同じドメインにある場合に限ります。そうでない場合、Webサイト1によって作成されたCookieはWebサイト2に送信されません。
私は最近、Single Sign-On Server/Client という非創造的な新製品をリリースしました。
http://barebonescms.com/documentation/sso/
現在、PHP サーバーとクライアントしかありません。これを使用することに興味がある場合は、PHP ホストにサーバー部分をインストールするのが最も理にかなっています。次に、ASP.NET および JSP 用の動作するクライアントを取得するために必要な移植作業があります。しかし、それはクロスドメインで機能します。現在、すべてのクライアント インスタンスで再度ログインする必要があることを警告しておきます。