17

Ownin Cookie 認証を持つ Mvc 5 クライアントがあります。また、Owin Bearer トークンで保護された Web Api もあります (トークン エンドポイントを作成する VS2013 Web Api テンプレートを使用しました)。

さて、私の Mvc 5 クライアントは私の 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を使用する必要があります...そのトークンを保持するにはどうすればよいですか(リクエストごとに新しいトークンを取得するにもかかわらず)、期限切れかどうかを確認するにはどうすればよいですか...可能ですか?それを認証Cookieと一緒に保持するにはどうすればよいですか? そのシナリオに対処するためのベストプラクティスはありますか?

ありがとう

4

3 に答える 3

16

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

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

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

それが正しければ、次のことができます。

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

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

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

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

于 2014-03-29T20:30:26.327 に答える
4

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

ここでは、ベアラー トークンをどのように使用する必要があるかについて説明します。クライアントは、トークンを安全な場所に保存し、すべてのリクエストで送信する責任があります.サーバーは、データベースでトークンを検索し、それが有効なものであることを確認する責任があります.".

クライアントがサービスと直接対話する単一ページ アプリケーションでベアラー トークンを使用する良い例を次に示します。

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

于 2014-03-29T20:33:13.587 に答える
2

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

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

于 2014-03-26T17:55:10.043 に答える