12

現在、ユーザーがウィジェットを表示および変更できる Web サイトを作成しています。サーバーに保存されているウィジェット データとのすべての対話は、RESTful Web サービスを介して行われます。たとえば、ユーザーが自分のウィジェットのリストを表示したい場合、実行の流れは次のようになります。

  1. ユーザー12345がサーバーにアクセスhttps://www.example.com/Login.htmして認証します(私の場合はOpenIDプロバイダーを介して)
  2. 次に、ユーザー 12345 がページにアクセスしますhttps://www.example.com/Widgets.htm
  3. サーバーは、Web サービスへのアクセスに使用される HTML ページと JavaScript で応答します。
  4. HTML ページが読み込まれると、javascript 関数getWidgets()が呼び出されます。getWidgets()私のWebサービスを呼び出しますhttps://www.example.com/Services/Widget/12345
  5. サービスは、別の JavaScript 関数renderWidgets(widgets)が HTML ページを更新するユーザー ウィジェットのリストで応答します。

ユーザー 12345 以外の誰も自分のウィジェットにアクセスしたくないのでgetWidgets()、Web サービスに何らかの認証を提供する必要があると思います。これを達成するための最善の方法が何であるかはわかりません。

クライアントとサーバーはgetWidgets()、Web サービスに送信される共有シークレットを持つことができると考えていました。サーバーは、このシークレットをランダムな文字列 (数値、GUID など) として生成し、クライアントが最初の HTML ページを要求したときに応答ヘッダーに含めることができます。クライアントは、サーバーにリクエストを送信するときにこの秘密鍵を使用します。

これは賢明な考えのように聞こえますか?

これは一般的な要件ですが、同じことを達成する標準的な方法はありますか? 私の知る限り、これは OpenID の範囲外であり、OAuth は適していません。

前もって感謝します。

4

3 に答える 3

9

これは素晴らしい質問ですが、あなたの解決策は、あなたが考えているよりも少し複雑である必要があると思います.

一般に、この種のシナリオを認証する方法は、2 段階のハンドシェイクです。最初のステップは、アプリケーションが実際に有効なクライアントであることを認証するために、(サーバーによって生成された、クライアント アプリケーションに固有の) 秘密鍵をサーバーに提供することです。これは、サーバーが認識し、信頼できるソフトウェアからの要求であるという信頼できる証拠をサーバーに提供するものです。

2 番目のステップは、ユーザーがクライアント アプリケーションにログインするときに、ユーザー名とパスワードの組み合わせを提供することです。この情報は、アプリケーション キーとともに、すべて SSL 経由でサーバーに送信する必要があります。

SSL はデータを暗号化して、パケット スニファーを使用するサードパーティが転送中のデータを読み取ることができないようにします。サーバーは次のことを行います。

  1. アプリケーション キーが有効であることを確認します。
  2. ユーザー名が存在し、アプリケーションに関連付けられていることを検証します。
  3. パスワードを暗号化し、ユーザー名に関連付けられたデータベース内の暗号化されたバージョンに対して暗号化されたバージョンをテストします。
  4. 上記のすべてのチェックに合格すると、サーバーはセッション ID を返します。この ID は、クライアント側の Cookie に入れることができ、後続の各要求でユーザーを再認証するために使用されます。いずれかのテストが失敗した場合 - サーバーは401: Unauthorized応答または他の同様のエラーを返します。

この時点で、クライアントは返されたセッション ID を利用でき、アプリケーション キーの再送信を続行する必要はありません。

あなたの申請

さて、あなたの場合、実際には同じアプリケーションと同じサーバーでクライアント/サーバーをホストしている可能性があります。この場合、一般に、アプリケーションのプライベート キーを中心に展開するすべての部分をスキップして、代わりにクロスサイト スクリプト リクエストを単純に禁止することができます。

なんで?- あなたが本当に保護しているのは次のようなものだからです:

サーバー A は RESTful API をホストします。クライアントの B、C、および D のホスト クライアントは、サーバー A の API に依存します。望ましくないのは、クライアント E (アプリケーションではなく、悪意のある) が、他のクライアントのいずれかの資格情報をバイパスまたは盗むことによって、サーバー A にアクセスできることです。

ただし、クライアントとサーバーの両方が同じ場所でホストされているため、同じ URL を持っている場合 (つまり、RESTful API が存在しwww.yourdomain.com/api、クライアントが存在するwww.yourdomain.com/場合)、通常、外部から発信された AJAX タイプのリクエストを許可することはできませんyourdomain.com。それがセキュリティのレイヤーです。

この場合、適切なレベルのセキュリティを確保するために必要なことは次のとおりです。

  1. サーバーの SSL を有効にします。
  2. へのリクエスト/auth/login(またはログインPOST方法が何であれ) のみを SSL 経由で受信できるようにします (C#[RequireHttps]では、メソッドまたはコントローラーの属性を使用してこれを行うことができます)。
  3. 独自のドメイン外から発信された AJAX リクエストを拒否します。
  4. Cookie で暗号化レイヤーを使用します。

クッキーには何を含める必要がありますか?

理想的には、Cookie には、サーバーのみが復号化できる双方向暗号化データが含まれている必要があります。言い換えれば、ユーザーのusernameまたはuser_idCookieの中に何かを入れることができますが、Rijndaelまたは別の暗号化システムを使用して双方向暗号化します-サーバーのみがアクセスできる暗号化パスワードを使用します(ランダムな文字列をお勧めします)。

次に、Cookie が添付された後続のリクエストを受信すると、次の操作を簡単に実行できます。

  1. Cookie が存在する場合は、プライベート パスワードを使用して復号化を試みます。
  2. 結果の復号化されたデータがガベージである場合 - 応答をスローします401: Unauthorized(これは変更された、または偽の Cookie です)
  3. 結果の復号化されたデータがデータベースと一致するユーザー名である場合 - 誰がリクエストを行っているかがわかり、それに応じてデータをフィルタリング/提供できます。

これが役立つことを願っています。:) そうでない場合は、お気軽にコメントを投稿して質問してください。明確にするよう努めます。

于 2012-11-01T23:36:58.773 に答える
2

これは、Web サービスへのリクエストを MAC するのと同じくらい簡単ではありませんか?

つまり、Web サービスを呼び出す JavaScript を提供しているので、この JavaScript 内にノンスを配置します。ほとんどの nonce 実装とは異なり、これはユーザー セッションの間有効です。

Web サービスを呼び出すとき、GetWidgets() の JavaScript はナンスをキーとして使用して「ランダムな」データをハッシュします。おそらく、文字列としてフォーマットされた時刻とデータ、ユーザーの ID (12345) をソルトとして使用します。 . 次に JavaScript は、ハッシュされたデータとハッシュされていない時間文字列を Web サービス呼び出しの一部として送信しますが、ノンスは送信しません。次に、送信された時間が最近のものであること(つまり、リプレイ攻撃を制限する最後の20秒)を確認し、サーバーがユーザーIDを使用して時間をソルトとしてハッシュし、ナンスを設定したことを確認します(設定されているため、それを認識しています)同じ結果が得られます。

そのため、サーバーによって設定され、クライアントに送信された共有キーを使用して、ハッシュ化されたメッセージ認証コード (MAC または HMAC) を生成するためのキーとして機能しましたが、リプレイ攻撃も防止しました (MAC はリクエストごとに異なり、再生ウィンドウが非常に短い)、Cookie のセッション情報を転送しないことで、セッションのハイジャックを防ぎます。


以前に特定のシナリオに出くわしたことはありませんが、すべてのメッセージで資格情報を送信したくない場合にメッセージを認証するという一般的な問題の特定のケースのようです。MACing は、これが行われるのを確実に見た方法です。

http://en.wikipedia.org/wiki/Message_authentication_codeを参照してください。MACing の概要がよくわかり、説明に役立つ図も含まれています。これはかなりよく使われている解決策です。私が推奨する唯一の逸脱は (私がそれに反抗したためです)、リプレイを防ぐためにメッセージに時間を含めることです。

これは、Last.fm が API へのアクセスを承認するために使用するアプローチの基礎です。このページ (呼び出しの署名) のパート 8 を参照してください: http://www.last.fm/api/authspec#8 . 彼らが使用しているハッシュは MD5 であり、クエリ文字列はハッシュされる本文テキストに含まれており、シークレットは最初の認証呼び出しから取得されたセッション キーを使用しています。

于 2012-11-29T19:32:47.823 に答える