ASP.NET Identity 入門

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

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

ASP.NET メンバーシップ

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

  • データベース スキーマは SQL Server 用に設計されており、変更できません。 プロファイル情報を追加することはできますが、追加データは別のテーブルにパックされるため、プロファイル プロバイダー API を使用する以外の方法ではアクセスが困難になります。
  • プロバイダー システムではバッキング データ ストアを変更できますが、このシステムは、リレーショナル データベースに適した想定に基づいて設計されています。 Azure Storage テーブルなどの非リレーショナル ストレージ メカニズムにメンバーシップ情報を保存するためのプロバイダーを作成できますが、この場合、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 と共にリリースされました。 シンプル メンバーシップの目的は、メンバーシップ機能を Web ページ アプリケーションに簡単に追加できるようにすることでした。

シンプル メンバーシップを使用すると、ユーザー プロファイル情報を簡単にカスタマイズできるようになりましたが、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 サイトなどのソーシャル チャネルを通じて、リアルタイムで相互にやり取りしています。 開発者は、ユーザーがソーシャル ID を使用してサインインすることで、開発者自身の Web サイトでユーザーが豊富なエクスペリエンスを得ることができるようにしたいと考えています。 最新のメンバーシップ システムでは、Facebook、Twitter などの認証プロバイダーへのリダイレクト ベースのログインを有効にする必要があります。

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

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

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

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

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

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

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

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

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

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

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

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

ASP.NET Identity の概要

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

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

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

    Image of new ASP dot Net project window

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

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

    Image of create new account

    ユーザーが [登録] ボタンを選択すると、次に示すように、アカウント コントローラーの 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.SignInAsync メソッドは ClaimsIdentity を生成します。 ASP.NET Identity と 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 Identity のコンポーネント

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

Diagram showing the components of the A S P dot Net identity system

以前に言及していない NuGet パッケージの簡単な説明を次に示します。

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

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

ASP.NET メンバーシップまたはシンプル メンバーシップを使用する既存のアプリを新しい ASP.NET Identity システムに移行するためのガイダンスを間もなく提供する予定です。

次のステップ