2

状況

Web ページが AJAX 呼び出しを行う予定のプロジェクトがあります。外部クライアントにも REST API が提供されます。ASP.NET MVC 4 と Web API を使用して、このプロジェクトを実装します。

[Authorize]人々がセキュリティのために属性を使用するさまざまな例をオンラインで見てきました。これは、Web ページで AJAX を介して Web API が呼び出されるたびに起こると思います。

API キーが各リクエストと共に (クエリ文字列またはヘッダーを介して) 渡されるさまざまな例も見てきました。これは、Web API が外部システムから呼び出されるたびに発生すると思います。

質問

すぐに頭に浮かぶ質問は次のとおりです。

  • 内部クライアントと外部クライアント用に別のコントローラーを作成する必要がありますか?
  • または、Web ページで同じ外部認証モデルを使用するように強制する必要がありますか?
  • または、外部クライアントが Authorize 属性を使用できる方法はありますか?
  • または、フォームまたは認証の両方を同時にサポートする必要がありますか?

補足事項

同僚は、Web アプリがホストされている場所とはまったく異なる URL に API をデプロイしたいかもしれないと指摘しました。同様に、彼は、外部 API をより粗くするか、個別に進化させる必要があるかもしれないと指摘しました。

ここで車輪を再発明したくありません。これは、そもそも Web API を AJAX 呼び出しの内部 API として使用する必要があるのか​​、それとも[HttpPost]属性を使用した古い学校の MVC アクションに固執する必要があるのか​​ 疑問に思います。

4

1 に答える 1

4

[Authorize]属性は Ajax だけを対象としたものではありません。属性を適用し[Authorize]てアクション メソッドを指定すると、リクエストを行うクライアントや API に送信される資格情報の種類に関係なく、アクション メソッドが実行される前に ID が認証されることが保証されます。探すのは だけですThread.CurrentPrincipalAuthorizeこれは、フィルターからのコードのコピーと貼り付けです。

protected virtual bool IsAuthorized(HttpActionContext actionContext)
{
    ...
    IPrincipal user = Thread.CurrentPrincipal;
    if (user == null || !user.Identity.IsAuthenticated)
    {
        return false;
    }
    ...
}

ご覧のとおりThread.CurrentPrincipal、ID が認証されているかどうかを取得して確認します。もちろん、ロールを含める場合は、追加のチェックがあります。

Thread.CurrentPrincipalつまり、認証の結果として が設定されている限り、さまざまな認証手段を使用できるということです。2 つのハンドラー (またはHttpModulesWeb ホスティングの場合) または Web API 2 の場合の認証フィルターがある場合、さまざまな要素に基づいて ID を確立できます。たとえば、 aBasicAuthnHandlerと a をApiKeyHandler追加しconfig.Handlersて、Web API パイプラインで次々に実行できます。彼らができることは、資格情報を探して設定することThread.CurrentPrincipalです。Authorizeヘッダーが基本スキームに含まれている場合BasicAuthnHandlerは認証および設定されThread.CurrentPrincipal、API キーが含まれている場合は何もせずにApiKeyHandler設定されますThread.CurrentPrincipal。両方のハンドラーが同じタイプのプリンシパル発言を作成できますGenericPrinicpalまたは別のもの。すべてのプリンシパルが を実装する必要があるため、これは問題ではありませんIPrincipal。そのため、Authorizeフィルターが実行Thread.CurrentPrincipalされるまでに設定され、認証方法に関係なく承認が機能します。注: Web ホストの場合はHttpContext.User、 に加えて、 も設定する必要がありますThread.CurrentPrincipal

于 2013-07-03T01:29:52.547 に答える