web-dev-qa-db-ja.com

トークン認証を使用してWebAPIにアクセスするMVC.NETCookie認証システム

OwninCookie認証を持つMvc5クライアントがあります。 OwinBearerトークンで保護されているWebApiもあります(トークンエンドポイントを作成するVS2013 Web Apiテンプレートを使用しました)

さて、Mvc5クライアントはWebApiを使用する必要があります。ベアラートークンを取得するメソッドを作成しました。

internal async Task<string> GetBearerToken(string siteUrl, string Username, string Password)
{
     HttpClient client = new HttpClient();

     client.BaseAddress = new Uri(siteUrl);
     client.DefaultRequestHeaders.Accept.Clear();

     HttpContent requestContent = new StringContent("grant_type=password&username=" + Username + "&password=" + Password, Encoding.UTF8, "application/x-www-form-urlencoded");

     HttpResponseMessage responseMessage = await client.PostAsync("Token", requestContent);

     if (responseMessage.IsSuccessStatusCode)
     {
         TokenResponseModel response = await responseMessage.Content.ReadAsAsync<TokenResponseModel>();
         return response.AccessToken;
     }

     return "";
}

そして私のMvcアクションで私はそれを呼んだ:

public async Task<ActionResult> Index()
{
     var token = await GetBearerToken("http://localhost:6144/", "teste", "123456");

     using (var client = new HttpClient())
     {
         client.DefaultRequestHeaders.Add("Authorization", "Bearer "+ token);

         var response = await client.GetAsync("http://localhost:6144/api/values");

         if (response.IsSuccessStatusCode)
         {
             var data = response.Content.ReadAsAsync<IEnumerable<string>>();

             return Json(data.Result, JsonRequestBehavior.AllowGet);
         }
     }   
}

それはすべて正常に機能します...しかし、すべてのアクションでWeb Apiを使用する必要があります...では、(リクエストごとに新しいトークンを取得しているにもかかわらず)そのトークンを保持する方法と、有効期限が切れているかどうかを確認する方法...可能ですか?どういうわけか認証クッキーと一緒にそれを保つために?そのシナリオに対処するためのベストプラクティスはありますか?

ありがとう

17
Paul

正しければ、MVC5クライアントアプリは別のアプリのWebAPIにアクセスしています。 MVC 5クライアントは、Cookieを使用してユーザーを認証します。 WebAPIにアクセスするには、/ TokenエンドポイントからBearerトーキーンを取得し、Authorizationヘッダーで送信します。

クライアント側のJavascriptコードからWebAPIを呼び出すのではなく、MVC5アプリケーションのサーバーで実行されているMVCアクション内から呼び出すだけです。

各サービス呼び出しの前に新しいトークンを取得するのは間違っているように聞こえます。これは、毎回2回の往復を意味します。これは実行できません。

私がそれを正しく理解した場合、あなたは次のことができます:

  1. トークンをSessionオブジェクトに保存します。 MVCアプリのユーザーが認証され、そのセッションが有効である限り、常に同じトークンを使用できます。有効期限が切れると、WebAPIから401の不正アクセスが返されます。 MVCアクションユニットをテスト可能に保つために、アクションに注入するサービスにセッションアクセスをラップすることができます(依存性注入)。

  2. トークンは、既存の認証Cookieと同様のCookieに保存できます。この方法では、サーバー側でセッションは必要ありません。ここでも、すべてのアクションが使用するサービスでCookieからトークンを取得するためのアクセスをラップします。

セッションストレージを使用します。シンプル。まっすぐ進む。しかし、多分私は何かが欠けています

これがお役に立てば幸いです。フィードバックを歓迎します:-)

14

ベアラートークンは、Webアプリケーションを承認するための良い方法ではありません。サービスのトークンをCookieに保存すると、アプリケーションのクライアントが利用できるようになるため、サービスレイヤーはアプリケーションのクライアントに対して脆弱になります。唯一の解決策はセッションでトークンを保持することのようですが、アプリケーションのステートレスな性質が失われます。

ベアラートークンの使用方法/使用方法について説明します: "ベアラートークンは、クライアントがすべてのAPI呼び出しで提示する必要のある大きなランダムな文字列です。ベアラートークンは、特別な署名がないため、またはどちらの側にも検証コードが必要です。クライアントはトークンを安全な場所に保存し、リクエストごとに送信する責任があります。サーバーはデータベースでトークンを検索し、それが有効なトークンであることを確認する責任があります。それだけです。 "。

これは、クライアントがサービスと直接通信する シングルページアプリケーション でベアラートークンを使用する良い例です。

とにかく、 HMAC認証 、BCryptまたはClientCertificatesを使用することをお勧めします。 Amazon でも、RESTリクエストの認証に使用します。

4
jan salawa

すべてのアクションでトークンを管理する場合は、カスタム認証フィルターを使用するようにコードを変更する必要があります。このフィルターは、すべてのWeb API要求、コントローラーのすべてのアクション、または個々のアクションに追加できます。これを行うには、AuthorizeAttributeから派生し、フィルターからGetBearerToken呼び出しを発行します。リクエスト処理中に使用できるように、トークンをHTTPコンテキストに貼り付けます。作成するHttpClientインスタンスを直接呼び出す代わりに、ファクトリを使用してインスタンスを生成し、認証用の適切なトークンを追加することができます。

トークンの有効期限が切れているかどうかを判断する場合は、戻ってくる特定のエラーをチェックするフィルターを追加するか、承認フィルターでチェックを発行することができます。私はあなたの要件のすべてを知っているわけではないので、そこで適切な解決策を決定することは困難です。

2
David Banister