ASP.NET Identity 入門

ASP.NET メンバーシップ システムは、2005 年に ASP.NET 2.0 で導入され、それ以来、Web アプリケーションが通常認証と承認を処理する方法に多くの変更が加えられました。 ASP.NET ID は、Web、電話、またはタブレット用の最新のアプリケーションを構築するときにメンバーシップ システムがどうあるべきかを新たに見てみましょう。

背景: ASP.NET のメンバーシップ

ASP.NET メンバーシップ

ASP.NET メンバーシップは、フォーム認証と、ユーザー名、パスワード、プロファイル データ用のSQL Server データベースを含む、2005 年に一般的だったサイト メンバーシップの要件を解決するように設計されました。 現在、Web アプリケーションにはさまざまなデータ ストレージ オプションがあり、ほとんどの開発者はサイトで認証と承認機能にソーシャル ID プロバイダーを使用できるようにしたいと考えています。 ASP.NET メンバーシップの設計の制限により、この移行が困難になります。

  • データベース スキーマはSQL Server用に設計されており、変更することはできません。 プロファイル情報を追加することはできますが、追加のデータは別のテーブルにパックされるため、プロファイル プロバイダー API を使用する以外の方法ではアクセスが困難になります。
  • プロバイダー システムを使用するとバッキング データ ストアを変更できますが、システムはリレーショナル データベースに適した想定に基づき設計されています。 Azure Storage Tables などの非リレーショナル ストレージ メカニズムにメンバーシップ情報を格納するプロバイダーを作成できますが、NoSQL データベースに適用されないメソッドに対して多くのコードと多くの System.NotImplementedException 例外を記述することで、リレーショナル設計を回避する必要があります。
  • ログイン/ログアウト機能はフォーム認証に基づいているため、メンバーシップ システムでは OWIN を使用できません。 OWIN には認証用のミドルウェア コンポーネントが含まれています。これには、外部 ID プロバイダー (Microsoft アカウント、Facebook、Google、Twitter など) を使用したログインのサポート、オンプレミスの Active Directoryまたは Azure Active Directory の組織アカウントを使用したログインが含まれます。 OWIN には、OAuth 2.0、JWT、CORS のサポートも含まれています。

ASP.NET シンプル メンバーシップ

ASP.NET 単純なメンバーシップは、ASP.NET Web ページのメンバーシップ システムとして開発されました。 WebMatrix と Visual Studio 2010 SP1 でリリースされました。 Simple Membership の目的は、Web ページ アプリケーションにメンバーシップ機能を簡単に追加できるようにするためでした。

Simple Membership を使用すると、ユーザー プロファイル情報を簡単にカスタマイズできるようになりましたが、ASP.NET メンバーシップに関するその他の問題は引き続き共有され、いくつかの制限があります。

  • 非リレーショナル ストアにメンバーシップ システム データを保持するのは困難でした。
  • OWIN では使用できません。
  • 既存の ASP.NET メンバーシップ プロバイダーではうまく機能せず、拡張可能ではありません。

ASP.NET ユニバーサル プロバイダー

ASP.NET ユニバーサル プロバイダーは、メンバーシップ情報をMicrosoft Azure SQL Databaseに保持できるように開発され、SQL Server Compactでも動作します。 ユニバーサル プロバイダーは Entity Framework Code First 上に構築されています。つまり、ユニバーサル プロバイダーを使用して、EF でサポートされている任意のストアにデータを保持できます。 ユニバーサル プロバイダーでは、データベース スキーマもかなりクリーンアップされました。

ユニバーサル プロバイダーは、ASP.NET メンバーシップ インフラストラクチャ上に構築されているため、SqlMembership プロバイダーと同じ制限が引き続き適用されます。 つまり、リレーショナル データベース用に設計されており、プロファイルとユーザー情報をカスタマイズするのは困難です。 これらのプロバイダーは、サインインとサインアウトの機能にもフォーム認証を使用します。

ASP.NET Identity

ASP.NET のメンバーシップストーリーが長年にわたって進化するにつれて、ASP.NET チームは顧客からのフィードバックから多くのことを学びました。

ユーザーが自分のアプリケーションに登録したユーザー名とパスワードを入力してサインインするという前提は、もはや有効ではありません。 Web はよりソーシャルになっています。 ユーザーは、Facebook、Twitter、その他のソーシャル Web サイトなどのソーシャル チャネルを通じて、リアルタイムで相互にやり取りしています。 開発者は、ユーザーが自分の Web サイトで豊富なエクスペリエンスを得ることができるように、ソーシャル ID でサインインできるようにしたいと考えています。 最新のメンバーシップ システムでは、Facebook、Twitter などの認証プロバイダーへのリダイレクトベースのログインを有効にする必要があります。

Web 開発が進化するにつれて、Web 開発のパターンも進化しました。 アプリケーション コードの単体テストは、アプリケーション開発者にとって重要な関心事となりました。 2008 ASP.NET では、開発者が単体テスト可能な ASP.NET アプリケーションを構築するのに役立つ一部として、Model-View-Controller (MVC) パターンに基づく新しいフレームワークが追加されました。 アプリケーション ロジックを単体テストする必要がある開発者も、メンバーシップ システムでこれを行えるようにしたいと考えていました。

Web アプリケーション開発におけるこれらの変更を考慮して、ASP.NET Identity は次の目標を持って開発されました。

  • 1 つの ASP.NET ID システム

    • ASP.NET ID は、ASP.NET MVC、Web Forms、Web ページ、Web API、SignalR など、すべての ASP.NET フレームワークで使用できます。
    • ASP.NET ID は、Web、電話、ストア、またはハイブリッド アプリケーションを構築するときに使用できます。
  • ユーザーに関するプロファイル データを簡単に接続

    • ユーザー情報とプロファイル情報のスキーマを制御できます。 たとえば、ユーザーがアプリケーションにアカウントを登録するときに入力した生年月日をシステムで簡単に保存できます。
  • 永続化コントロール

    • 既定では、ASP.NET ID システムは、すべてのユーザー情報をデータベースに格納します。 ASP.NET ID では、Entity Framework Code First を使用して、すべての永続化メカニズムを実装します。
    • データベース スキーマを制御するため、テーブル名の変更や主キーのデータ型の変更などの一般的なタスクは簡単に実行できます。
    • 例外をスロー System.NotImplementedExceptions することなく、SharePoint、Azure Storage Table Service、NoSQL データベースなどのさまざまなストレージ メカニズムを簡単にプラグインできます。
  • 単体テストの容易性

    • ASP.NET ID を使用すると、Web アプリケーションの単体テストが容易になります。 ASP.NET ID を使用するアプリケーションの部分の単体テストを記述できます。
  • ロール プロバイダー

    • ロール によってアプリケーションの一部へのアクセスを制限できるロール プロバイダーがあります。 "管理" などのロールを簡単に作成し、ロールにユーザーを追加できます。
  • 要求ベース

    • ASP.NET ID はクレーム ベースの認証をサポートします。ここで、ユーザーの ID はクレームのセットとして表されます。 要求を使用すると、開発者はロールが許可するよりも、ユーザーの ID を記述する方がはるかに表現力豊かになります。 ロール メンバーシップはブール値 (メンバーまたは非メンバー) に過ぎませんが、要求にはユーザーの ID とメンバーシップに関する豊富な情報を含めることができます。
  • ソーシャル ログイン プロバイダー

    • Microsoft アカウント、Facebook、Twitter、Google などのソーシャル ログインをアプリケーションに簡単に追加し、ユーザー固有のデータをアプリケーションに格納できます。
  • OWIN 統合

    • ASP.NET 認証は、OWIN ベースのホストで使用できる OWIN ミドルウェアに基づいています。 ASP.NET ID は System.Web に依存しません。 これは完全に準拠した OWIN フレームワークであり、OWIN でホストされている任意のアプリケーションで使用できます。
    • ASP.NET ID は、Web サイト内のユーザーのログイン/ログアウトに OWIN 認証を使用します。 つまり、FormsAuthentication を使用して Cookie を生成する代わりに、アプリケーションは OWIN CookieAuthentication を使用してこれを行います。
  • NuGet パッケージ

    • ASP.NET ID は、Visual Studio 2017 に付属する ASP.NET MVC、Web Forms、Web API テンプレートにインストールされている NuGet パッケージとして再配布されます。 この NuGet パッケージは、NuGet ギャラリーからダウンロードできます。
    • ASP.NET ID を NuGet パッケージとしてリリースすると、ASP.NET チームは新機能やバグ修正を簡単に反復し、アジャイルな方法で開発者に提供できます。

ASP.NET ID の概要

ASP.NET ID は、ASP.NET MVC、Web Forms、Web API、SPA 用の Visual Studio 2017 プロジェクト テンプレートで使用されます。 このチュートリアルでは、プロジェクト テンプレートで ASP.NET ID を使用して、ユーザーを登録、サインイン、サインアウトする機能を追加する方法について説明します。

ASP.NET ID は、次の手順を使用して実装されます。 この記事の目的は、ASP.NET ID の概要を説明することです。あなたはステップバイステップでそれに従うか、単に詳細を読むことができます。 新しい API を使用してユーザー、ロール、プロファイル情報を追加するなど、ASP.NET ID を使用してアプリを作成する方法の詳細については、この記事の最後にある「次の手順」セクションを参照してください。

  1. 個々のアカウントを使用して ASP.NET MVC アプリケーションを作成します。 ASP.NET ID は、ASP.NET MVC、Web Forms、Web API、SignalR などで使用できます。この記事では、ASP.NET MVC アプリケーションから始めます。

    新しい ASP Dot Net プロジェクト ウィンドウの画像

  2. 作成されたプロジェクトには、ASP.NET ID 用の次の 3 つのパッケージが含まれています。

    • Microsoft.AspNet.Identity.EntityFramework
      このパッケージには、ASP.NET ID データとスキーマをSQL Serverに保持する、ASP.NET ID の Entity Framework 実装があります。
    • Microsoft.AspNet.Identity.Core
      このパッケージには、ASP.NET ID のコア インターフェイスがあります。 このパッケージを使用すると、Azure Table Storage、NoSQL データベースなど、さまざまな永続化ストアを対象とする ASP.NET ID の実装を記述できます。
    • Microsoft.AspNet.Identity.OWIN
      このパッケージには、ASP.NET アプリケーションで OWIN 認証と ASP.NET ID を接続するために使用される機能が含まれています。 これは、アプリケーションにサインイン機能を追加し、OWIN Cookie 認証ミドルウェアを呼び出して Cookie を生成するときに使用されます。
  3. ユーザーの作成。
    アプリケーションを起動し、[ 登録 ] リンクをクリックしてユーザーを作成します。 次の図は、ユーザー名とパスワードを収集する [登録] ページを示しています。

    新しいアカウントの作成の画像

    ユーザーが [登録 ] ボタンを選択すると、次に強調表示されているように、 Register アカウント コントローラーのアクションによって、ASP.NET Identity API を呼び出してユーザーが作成されます。

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser() { UserName = model.UserName };
            var result = await UserManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                await SignInAsync(user, isPersistent: false);
                return RedirectToAction("Index", "Home");
            }
            else
            {
                AddErrors(result);
            }
        }
    
        // If we got this far, something failed, redisplay form
        return View(model);
    }
    
  4. サインインします。
    ユーザーが正常に作成された場合は、 メソッドによって SignInAsync サインインされます。

     [HttpPost]
     [AllowAnonymous]
     [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
            var result = await UserManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                 await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
                        
                 // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
                 // Send an email with this link
                 // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                 // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                 // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");
    
                 return RedirectToAction("Index", "Home");
             }
             AddErrors(result);
         }
    
        // If we got this far, something failed, redisplay form
         return View(model);
     }
    

    メソッドは SignInManager.SignInAsyncClaimsIdentity を生成します。 ASP.NET ID と OWIN Cookie 認証はクレーム ベースのシステムであるため、フレームワークでは、ユーザーの ClaimsIdentity を生成する必要があります。 ClaimsIdentity には、ユーザーが属しているロールなど、ユーザーのすべての要求に関する情報があります。

  5. ログオフします。
    [ ログオフ ] リンクを選択して、アカウント コントローラーで LogOff アクションを呼び出します。

    // POST: /Account/LogOff
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult LogOff()
    {
        AuthenticationManager.SignOut();
        return RedirectToAction("Index", "Home");
    }
    

    上記の強調表示されたコードは、OWIN AuthenticationManager.SignOut メソッドを示しています。 これは、Web Formsの FormsAuthentication モジュールで使用される FormsAuthentication.SignOut メソッドに似ています。

ASP.NET ID のコンポーネント

次の図は、ASP.NET ID システムのコンポーネントを示しています ( これを 選択するか、図を選択して拡大します)。 緑色のパッケージは、ASP.NET ID システムを構成します。 他のすべてのパッケージは、ASP.NET アプリケーションで ASP.NET ID システムを使用するために必要な依存関係です。

A S P ドット Net ID システムのコンポーネントを示す図

前に説明しなかった NuGet パッケージの簡単な説明を次に示します。

  • Microsoft.Owin.Security.Cookies
    アプリケーションが ASP と同様に Cookie ベースの認証を使用できるようにするミドルウェア。NET のフォーム認証。
  • EntityFramework
    Entity Framework は、リレーショナル データベースに対して Microsoft が推奨するデータ アクセス テクノロジです。

メンバーシップから ASP.NET ID への移行

ASP.NET メンバーシップまたはシンプル メンバーシップを使用する既存のアプリを新しい ASP.NET ID システムに移行する方法について、間もなくガイダンスを提供したいと考えています。

次の手順