web-dev-qa-db-ja.com

JSONP / CORSを使用したシングルサインオンの設計?

OAuth/OpenIDが別のドメインのユーザーを認証/識別できる方法が好きですが、それは他のドメインが許可している場合に限られます(おそらくユーザーの指示による)。

同様のことをしたいのですが、CORS AJAXまたはJSONPのような代替手段を使用します。問題は、ページ全体のリダイレクトを使用する場合、「ログインドメイン」がどのドメインかを特定できることですHTTPリダイレクト自体を発行しているため、auth_token/infoを提供していますが、これはJSONPには当てはまりません。

私の現在の考えは以下であり、私の質問は次のとおりです。

  • このパターンの弱点は何ですか?
  • (CORS以外の場合)2つの個別のリクエストなしでこれを行う方法はありますか?

一般的なケース:

編集:このセクションはもともとJSONPリクエストを前提としていました-実際、それはあらゆるタイプのデータであると思います

ケースA:「cookieを使用して」「ログインドメイン」にログインしたユーザー

  1. クライアントは、「サービスドメイン」のURLを指定して、「ログインドメイン」にリクエストを行います。
  2. ログインサーバーは、指定されたURLを見て、「はい、それで結構です」と判断し、URLにauth_token/whateverを含むHTTPリダイレクト(3XX)応答を返します。
  3. クライアントはリダイレクトに従ってサービスドメインに戻ります。サービスドメインはauth_token/whateverをセッションに格納し、静的リソース(画像など)を返します
  4. 次にクライアントは、auth_token/whateverを取得するために、サービスドメイン(クロスオリジン不可)に2番目のリクエストを行います。

ケースB:ユーザーが「ログインドメイン」にログインしていないか、「サービスドメイン」との共有の詳細を承認していません。

  1. クライアントは、「サービスドメイン」のURLを指定して、「ログインドメイン」にリクエストを行います。
  2. ログインサーバーがHTTPリダイレクト(3XX)応答を返します。この応答には、URL(またはおそらくフルページのOAuthスタイルのログインのURL)に「未承認」ステータスが含まれています。
  3. クライアントはリダイレクトに従ってサービスドメインに戻ります。サービスドメインはセッションに「未承認」ステータスを保存し、静的リソースをクライアントに返します。
  4. 次に、クライアントはサービスドメイン(クロスオリジン不可)に2回目のリクエストを行い、認証/識別が失敗したことを確認します。

ケースC:他のサイトがログインステータスを検査しようとしている

  1. ユーザーは危険なサイトに移動します
  2. クライアントはログインサーバーにリクエストを送信し、actualサービスドメインのURLを提供します
  3. ログインサーバーは、実際のサービスドメインのページにリダイレクトし、静的な結果を返します。
  4. ユーザーはログインしている場合とログインしていない場合がありますが、クライアントは、それらを通知する「サービスドメイン」エンドポイントがクロスオリジン制限によって禁止されているため、検出できません。

CORS AJAXケース

「ログインサーバー」エンドポイントでCORSが有効になっている場合、リクエストはAJAXリクエストとして作成できます。「サービスドメイン」エンドポイントでCORSが有効になっていない場合、この最終結果は= AJAXリクエストは、2番目のリクエストを要求する代わりに、実際にはauth_token/whateverのエコーである可能性があります。

  1. クライアントはCORS AJAX=「ログインドメイン」へのリクエストを行い、「サービスドメイン」のURLを提供します
  2. ログインサーバーは、URLにauth_token/failure/whateverを含むHTTPリダイレクト(3XX)応答を返します。
  3. クライアントはリダイレクトに従ってサービスドメインに戻ります。
  4. サービスドメインは、URL(auth_token/whatever)で提供されるすべての情報を含むドキュメントを返します。

実際、この「auth_tokenをエコーする」動作は、上記のセクションの静的リソースの代わりに使用することもできるため、同じエンドポイントで両方のモデルをサポートできます。

9
cloudfeet

OAuthは柔軟であり、OAuthフローはアプリケーション固有のニーズに合わせて変更されます。最も一般的な2つのフローは 2-leggedおよび3-legged で、これらのフローの場合正しく実装されていれば、一般に安全であると認められています。

OAuthフローの提案されたCORS AJAX実装は、2つのセキュリティ要件に違反します RFC-6749-= OAuth 2.0 Authorization Framework 。この標準からの逸脱により、Authorization Serverがクライアントを適切に検証する機能と、クライアントの意図が損なわれます。

  1. 悪意のあるJavaScriptクライアントが認可サーバーとのやり取りを改ざんしないようにするためのコントロールが必要です。 URLがCORS Ajaxリクエスト内の引数として提供される場合、 HTTP Originヘッダー をチェックするのではなく、悪意のあるクライアントがそのコンテキストを偽ることが許可されます。さらに、リダイレクトは許可サーバーとクライアントの相互認証に使用されます。これらの制御を適切に行わないことは RFC-6749-10.2クライアントの偽装 の違反です。

    悪意のあるクライアントは、別のクライアントになりすまして、偽装されたクライアントがクライアントの資格情報を秘密にしておくことができないかできない場合、保護されたリソースへのアクセスを取得できます。

    許可サーバーは、可能な限りクライアントを認証する必要があります。承認サーバーがクライアントの性質によりクライアントを認証できない場合、承認サーバーは承認応答の受信に使用されるリダイレクトURIの登録を要求しなければならず、そのような潜在的に悪意のあるクライアントからリソース所有者を保護するために他の手段を利用する必要があります。たとえば、承認サーバーは、リソースの所有者に依頼して、クライアントとそのオリジンの識別を支援できます。

  2. OAuthフローはユーザーが開始する必要があります。 OAuth状態パラメーターはCSRFを防ぐために使用されます 認証を確立するとき。ユーザーにWebアプリケーションへのログインを強制することは、セッションに乗る攻撃チェーンの便利なリンク。セッションが確立された後、攻撃者はCSRFまたはXSSを使用して新しく作成されたセッションを制御できます。このコンテキストでユーザーの意図を証明できないと、 RFC- 6749-10.12。クロスサイトリクエストフォージェリ

    クライアントのリダイレクトURIに対するCSRF攻撃により、攻撃者は独自の認証コードまたはアクセストークンを挿入できます。これにより、クライアントは被害者ではなく、攻撃者の保護されたリソースに関連付けられたアクセストークンを使用する可能性があります(たとえば、被害者の銀行口座情報を保存します)攻撃者によって制御されている保護されたリソースに)。

6
rook