13

WebAPI の一般的な使用例は、データにアクセスするために API をヒットする JavaScript を含む MVC コントローラーによってシェル ビューをレンダリングすることです。

しかし、高価な API 操作がいくつかあり、それらのエンドポイントにリモートでアクセスする人を望まない場合、アプリケーションによって配信される MVC ビューのみがそれらにアクセスできるようにしたいとします。どうすればそれらを保護できますか?

この場合Request.IsLocal、javascript がマシン上のクライアントのブラウザーから呼び出しているため、機能しません。それが機能したとしても、HttpContextこのプロパティを見つけるために実際の値を取得する必要があります。そのソリューションは、セルフホステッド WebAPI では機能しません。

有効な を必要とする API エンドポイントの場合、属性IPrincipalでそれらを保護できます。[Authorize]しかし、アプリが匿名ユーザーにアクセスできるようにする API エンドポイントについてはどうでしょうか?

私は解決策を試しましたが、それが最善の(または良い)アプローチであるかどうかわからないため、回答として個別に投稿します。

4

2 に答える 2

2

MVC サイトで認証を使用している場合は、Web API メソッドのフォーム認証を有効にすることができます。[Authorize]AJAX 呼び出しから送信されるフォーム認証 Cookie の存在をチェックするカスタム属性を作成し、存在する場合はプリンシパルを作成できます。

もう 1 つの考えられる解決策はtokens、より RESTful なスタイルで API を保護することです。ここでの考え方は、ユーザーが MVC Web サイトで認証するときに、トークンを生成してビューに渡すことができます。このトークンは、AJAX 要求を Web API に送信するときに使用され、トークンとその署名の有効性が検証されます。

一方、サイトで認証を使用していない場合、JavaScript を使用して API メソッドを呼び出しているため、リクエストが信頼できるクライアントからのものかどうかを知る方法がないため、状況は非常に複雑になります。

于 2013-03-12T16:21:01.410 に答える
2

「何を試しましたか」と口論する前に、私が試したことを次に示します。できます。より良い方法があるかどうかはわかりません。

  1. MVC アクション フィルターを作成し、 中にグローバル フィルターとして追加しますApplication_Start

  2. Http (WebAPI) アクション フィルターを作成し、リモート リクエストを拒否する必要があるアクションで使用します。

グローバル MVC フィルターはこれを行います。

  1. リクエストで特定の Cookie を探します。Cookie が存在する場合、その値は復号化されます。復号化された値は の文字列表現である必要があるDateTimeため、 を使用DateTime.TryParseして取得します。値が に正しく解析され、DateTimeそれDateTimeが 1 日未満である場合は、ここで停止し、他に何もしません。

  2. Cookie が存在しない、復号化/解析できない、または 1 日以上経過している場合は、新しい Cookie をブラウザーに書き込みます。現在DateTime.UtcNow.ToString()を値として使用し、それを暗号化し、 で書き込みますHttpOnly = false

WebAPI フィルターはこれを行います。

  1. リクエストで特定の Cookie を探します。Cookie が存在する場合は、その値を復号化し、DateTime.

  2. 値が有効DateTimeで、2 日以内である場合は、ここで停止し、他に何もしません。

  3. それ以外の場合は、403 Forbidden 例外をスローします。

これの私の現在の実装に関するいくつかのメモ。まず、共有シークレットとソルトを使用した AES 暗号化を使用します。共有シークレットはappSetting、web.config に として保存されます。ソルトについては、匿名識別を有効にRequest.AnonymousIDしてソルトとして使用しました。私はソルトが完全に好きというわけではありません。なぜなら、WebAPI コントローラーで取得するのはトリッキーだからですが、自己ホストされていない限り不可能ではありません。

于 2013-03-12T16:23:01.567 に答える