web-dev-qa-db-ja.com

ASP.NET Web APIでのユーザー認証

このトピックは、私にとって非常に紛らわしいものです。私はHTTPアプリの新人ですが、どこかからJSONデータを消費するiPhoneクライアントを開発する必要があります。 MSからWeb APIを選んだのは、簡単だと思えたからですが、ユーザーの認証に関しては、非常にイライラします。

Googlingの数時間後にログイン画面からAuthorizeメソッドを介してApiController属性を使用してユーザーを認証する方法の明確な例を見つけることができなかったことに驚いています。

これは質問ではなく、これを正確に行う方法の例のリクエストです。私は次のページを見ました:

これらは無許可のリクエストの処理方法を説明していますが、LoginControllerのようなものや、ユーザー資格情報を要求して検証するようなものを明確に示していません。

ニースの簡単な例を書いてくれたり、正しい方向に向けてくれませんか?

ありがとう。

146
Luis Aguilar

数時間のGoogle検索の後、ログイン画面からApiControllerメソッドでAuthorize属性を使用してユーザーを認証する方法の明確な例を見つけることができなかったことに驚かされます。

これは、次の2つの概念について混乱しているためです。

  • 認証は、システムがユーザーを安全に識別できるメカニズムです。認証システムは、質問への回答を提供します。

    • ユーザーは誰ですか?
    • ユーザーは本当に自分を代表するユーザーですか?
  • 承認とは、特定の認証済みユーザーがシステムによって制御されているリソースを保護するために必要なアクセスレベルをシステムが決定するメカニズムです。たとえば、データベース管理システムは、特定の特定の個人にデータベースから情報を取得する機能を提供するように設計されていますが、他の個人にデータを変更する機能を提供する一方で、datbaseに格納されたデータを変更することはできません。承認システムは、質問への回答を提供します。

    • ユーザーXはリソースRへのアクセスを許可されていますか?
    • ユーザーXには、操作Pを実行する権限がありますか?
    • ユーザーXは、リソースRで操作Pを実行することを許可されていますか?

MVCのAuthorize属性は、次のようにアクセスルールを適用するために使用されます。

 [System.Web.Http.Authorize(Roles = "Admin, Super User")]
 public ActionResult AdministratorsOnly()
 {
     return View();
 }

上記のルールでは、AdminおよびSuper Userロールのユーザーのみがメソッドにアクセスできます

これらのルールは、location要素を使用してweb.configファイルで設定することもできます。例:

  <location path="Home/AdministratorsOnly">
    <system.web>
      <authorization>
        <allow roles="Administrators"/>
        <deny users="*"/>
      </authorization>
    </system.web>
  </location>

ただし、これらの許可ルールを実行する前に、現在のWebサイトに対して認証を受ける必要があります

これらは無許可のリクエストの処理方法を説明していますが、LoginControllerなどのようなユーザークレデンシャルを要求して検証するようなものを明確に示していません。

ここから、問題を2つに分けることができます。

  • 同じWebアプリケーション内でWeb APIサービスを使用するときにユーザーを認証する

    ASP.Netでの認証 に依存するため、これが最も簡単なアプローチです。

    これは簡単な例です:

    Web.config

    <authentication mode="Forms">
      <forms
        protection="All"
        slidingExpiration="true"
        loginUrl="account/login"
        cookieless="UseCookies"
        enableCrossAppRedirects="false"
        name="cookieName"
      />
    </authentication>
    

    ユーザーはaccount/loginルートにリダイレクトされます。そこで、ユーザー資格情報を要求するカスタムコントロールをレンダリングし、次を使用して認証Cookieを設定します。

        if (ModelState.IsValid)
        {
            if (Membership.ValidateUser(model.UserName, model.Password))
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
        }
    
        // If we got this far, something failed, redisplay form
        return View(model);
    
  • クロスプラットフォーム認証

    この場合は、Webアプリケーション内でWeb APIサービスのみを公開している場合です。したがって、別のクライアントがサービスを使用している場合、クライアントは別のクライアントである可能性がありますWebアプリケーションまたは任意の.Netアプリケーション(Winフォーム、WPF、コンソール、Windowsサービスなど)

    たとえば、同じネットワークドメイン(イントラネット内)の別のWebアプリケーションからWeb APIサービスを使用すると仮定します。この場合、ASP.Netによって提供されるWindows認証に依存できます。

    <authentication mode="Windows" />
    

    サービスがインターネットに公開されている場合、認証されたトークンを各Web APIサービスに渡す必要があります。

    詳細については、次の記事をご覧ください。

176
Jupaol

ユーザー名とパスワードおよび認証Cookieなしのに対して認証したい場合、MVC4 Authorize 属性はそのままでは機能しません。ただし、次のヘルパーメソッドをコントローラーに追加して、基本認証ヘッダーを受け入れることができます。コントローラーのメソッドの最初から呼び出します。

void EnsureAuthenticated(string role)
{
    string[] parts = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(Request.Headers.Authorization.Parameter)).Split(':');
    if (parts.Length != 2 || !Membership.ValidateUser(parts[0], parts[1]))
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "No account with that username and password"));
    if (role != null && !Roles.IsUserInRole(parts[0], role))
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "An administrator account is required"));
}

クライアント側から、このヘルパーは所定の位置に認証ヘッダーを持つHttpClientを作成します。

static HttpClient CreateBasicAuthenticationHttpClient(string userName, string password)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(userName + ':' + password)));
    return client;
}
15
Edward Brey

私はMVC5/Web APIプロジェクトに取り組んでおり、Web Apiメソッドの承認を取得できる必要がありました。インデックスビューが最初に読み込まれると、自動的に作成されると考えられる「トークン」Web APIメソッドを呼び出します。

トークンを取得するクライアント側コード(CoffeeScript)は次のとおりです。

getAuthenticationToken = (username, password) ->
    dataToSend = "username=" + username + "&password=" + password
    dataToSend += "&grant_type=password"
    $.post("/token", dataToSend).success saveAccessToken

成功すると、以下が呼び出され、認証トークンがローカルに保存されます。

saveAccessToken = (response) ->
    window.authenticationToken = response.access_token

次に、[Authorize]タグを持つWeb APIメソッドに対してAjax呼び出しを行う必要がある場合、Ajax呼び出しに次のヘッダーを追加するだけです。

{ "Authorization": "Bearer " + window.authenticationToken }
9
ProfNimrod