ASP.NET Identity を空または既存の Web フォーム プロジェクトに追加する

このチュートリアルでは、 ASP.NET ID (ASP.NET の新しいメンバーシップ システム) を ASP.NET アプリケーションに追加する方法について説明します。

Visual Studio 2017 RTM で個別のアカウントを使用して新しいWeb Formsまたは MVC プロジェクトを作成すると、Visual Studio によって必要なすべてのパッケージがインストールされ、必要なすべてのクラスが追加されます。 このチュートリアルでは、既存のWeb Forms プロジェクトまたは新しい空のプロジェクトに ASP.NET ID サポートを追加する手順について説明します。 インストールする必要があるすべての NuGet パッケージと、追加する必要があるクラスについて説明します。 新しいユーザーを登録してログインするためのサンプル Web Formsを確認しながら、ユーザー管理と認証のためのすべてのメインエントリ ポイント API を強調表示します。 このサンプルでは、Entity Framework 上に構築された SQL データ ストレージの ASP.NET ID の既定の実装を使用します。 このチュートリアルでは、SQL データベースに LocalDB を使用します。

ASP.NET ID の概要

  1. まず、 Visual Studio 2017 をインストールして実行します。

  2. [スタート] ページから [新しいプロジェクト ] を選択するか、メニューを使用して [ ファイル] を選択し、[ 新しいプロジェクト] を選択します。

  3. 左側のウィンドウで [ Visual C#] を展開し、[ Web] を選択し、[ Web アプリケーション (.Net Framework)] を ASP.NET します。 プロジェクトに "WebFormsIdentity" という名前を付け、[ OK] を選択します

    新しいプロジェクトの作成を表示する画像

  4. [ 新しい ASP.NET プロジェクト ] ダイアログで、 のテンプレートを選択します。

    新しい A S P ドット N E T プロジェクト ダイアログ ウィンドウ

    [ 認証の変更 ] ボタンが無効になっており、このテンプレートでは認証のサポートが提供されていないことに注意してください。 Web Forms、MVC、Web API テンプレートを使用すると、認証方法を選択できます。

アプリに ID パッケージを追加する

ソリューション エクスプローラーでプロジェクトを右クリックし、[NuGet パッケージの管理] を選択します。 Microsoft.AspNet.Identity.EntityFramework パッケージを検索してインストールします。

Nu Get パッケージの管理にアクセスする方法を示す画像

このパッケージでは、 EntityFrameworkMicrosoft ASP.NET Identity Core の依存関係パッケージがインストールされることに注意してください。

ユーザーを登録する Web フォームを追加する

  1. ソリューション エクスプローラーでプロジェクトを右クリックし、[追加]、[Web フォーム] の順に選択します。

    登録済みユーザーに Web フォームを追加する方法を示す画像

  2. [アイテムの名前の指定] ダイアログ ボックスで、新しい Web フォームに Register という名前を付け、[OK] を選択します

  3. 生成された Register.aspx ファイル内のマークアップを次のコードに置き換えます。 コードの変更が強調表示されています。

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Register.aspx.cs" Inherits="WebFormsIdentity.Register" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body style="font-family: Arial, Helvetica, sans-serif; font-size: small">
        <form id="form1" runat="server">
        <div>
            <h4 style="font-size: medium">Register a new user</h4>
            <hr />
            <p>
                <asp:Literal runat="server" ID="StatusMessage" />
            </p>                
            <div style="margin-bottom:10px">
                <asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
                <div>
                    <asp:TextBox runat="server" ID="UserName" />                
                </div>
            </div>
            <div style="margin-bottom:10px">
                <asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
                <div>
                    <asp:TextBox runat="server" ID="Password" TextMode="Password" />                
                </div>
            </div>
            <div style="margin-bottom:10px">
                <asp:Label runat="server" AssociatedControlID="ConfirmPassword">Confirm password</asp:Label>
                <div>
                    <asp:TextBox runat="server" ID="ConfirmPassword" TextMode="Password" />                
                </div>
            </div>
            <div>
                <div>
                    <asp:Button runat="server" OnClick="CreateUser_Click" Text="Register" />
                </div>
            </div>
        </div>
        </form>
    </body>
    </html>
    

    Note

    これは、新しい ASP.NET Web Forms プロジェクトを作成するときに作成される Register.aspx ファイルの簡略化されたバージョンです。 上記のマークアップでは、フォーム フィールドと、新しいユーザーを登録するためのボタンが追加されます。

  4. Register.aspx.cs ファイルを開き、ファイルの内容を次のコードに置き換えます。

    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using System;
    using System.Linq;
    
    namespace WebFormsIdentity
    {
       public partial class Register : System.Web.UI.Page
       {
          protected void CreateUser_Click(object sender, EventArgs e)
          {
             // Default UserStore constructor uses the default connection string named: DefaultConnection
             var userStore = new UserStore<IdentityUser>();
             var manager = new UserManager<IdentityUser>(userStore);
    
             var user = new IdentityUser() { UserName = UserName.Text };
             IdentityResult result = manager.Create(user, Password.Text);
    
             if (result.Succeeded)
             {
                StatusMessage.Text = string.Format("User {0} was created successfully!", user.UserName);
             }
             else
             {
                StatusMessage.Text = result.Errors.FirstOrDefault();
             }
          }
       }
    }
    

    Note

    1. 上記のコードは、新しい ASP.NET Web Forms プロジェクトを作成するときに作成される Register.aspx.cs ファイルの簡略化されたバージョンです。
    2. IdentityUser クラスは、IUser インターフェイスの既定の EntityFramework 実装です。 IUser インターフェイスは、ASP.NET Identity Core 上のユーザーの最小インターフェイスです。
    3. UserStore クラスは、ユーザー ストアの既定の EntityFramework 実装です。 このクラスは、ASP.NET Identity Core の最小インターフェイス (IUserStoreIUserLoginStoreIUserClaimStoreIUserRoleStore) を実装します
    4. UserManager クラスは、UserStore への変更を自動的に保存するユーザー関連 API を公開します。
    5. IdentityResult クラスは、ID 操作の結果を表します。
  5. ソリューション エクスプローラーでプロジェクトを右クリックし、[追加]、[ASP.NET フォルダーの追加] の順に選択し、App_Dataします。

    アプリ データを追加する方法の図

  6. Web.config ファイルを開き、ユーザー情報の格納に使用するデータベースの接続文字列エントリを追加します。 データベースは、実行時に Identity エンティティの EntityFramework によって作成されます。 接続文字列は、新しいWeb Forms プロジェクトを作成するときに作成されたものと似ています。 強調表示されたコードは、追加する必要があるマークアップを示しています。

    <?xml version="1.0" encoding="utf-8"?>
    <!--
      For more information on how to configure your ASP.NET application, please visit
      https://go.microsoft.com/fwlink/?LinkId=169433
      -->
    <configuration>
      <configSections>
        <!-- For more information on Entity Framework configuration, visit https://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      </configSections>
       <connectionStrings>
          <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\WebFormsIdentity.mdf;Initial Catalog=WebFormsIdentity;Integrated Security=True"
                providerName="System.Data.SqlClient" />
       </connectionStrings>
      <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
      </system.web>
      <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
          <parameters>
            <parameter value="v11.0" />
          </parameters>
        </defaultConnectionFactory>
        <providers>
          <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
        </providers>
      </entityFramework>
    </configuration>
    

    Note

    Visual Studio 2015 以降の場合は、接続文字列で を に置き換えます(localdb)\v11.0(localdb)\MSSQLLocalDB

  7. プロジェクトで Register.aspx ファイルを右クリックし、[ スタート ページとして設定] を選択します。 Ctrl + F5 キーを押して Web アプリケーションをビルドし、実行します。 新しいユーザー名とパスワードを入力し、[ 登録] を選択します。

    新しいユーザー登録に成功したイメージ

    Note

    ASP.NET Identity は検証をサポートしており、このサンプルでは、Identity Core パッケージから取得したユーザー検証コントロールとパスワード検証コントロールで既定の動作を確認できます。 User (UserValidator) の既定の検証コントロールには、既定値が にtrue設定された プロパティAllowOnlyAlphanumericUserNamesがあります。 パスワード (MinimumLengthValidator) の既定の検証コントロールでは、パスワードの文字数が少なくとも 6 文字であることを確認します。 これらの検証コントロールは、カスタム検証を行う場合にオーバーライドできる の UserManager プロパティです。

Entity Framework によって生成された LocalDb ID データベースとテーブルを確認する

  1. [表示] メニューの [サーバー エクスプローラー] を選択します。

    サーバー エクスプローラーにアクセスする方法の画像

  2. [DefaultConnection (WebFormsIdentity)] を展開し、[テーブル] を展開し、[AspNetUsers] を右クリックして、[テーブル データの表示] を選択します。

    テーブル データの表示にアクセスする方法の画像
    登録済みユーザーのテーブル データを表示する画像

OWIN 認証用にアプリケーションを構成する

この時点で、ユーザーの作成のサポートのみが追加されました。 次に、ユーザーにログインするための認証を追加する方法を示します。 ASP.NET ID では、フォーム認証に Microsoft OWIN 認証ミドルウェアが使用されます。 OWIN Cookie 認証は、 OWIN または IIS でホストされている任意のフレームワークで使用できる Cookie およびクレーム ベースの認証メカニズムです。 このモデルでは、ASP.NET MVC や Web Forms を含む複数のフレームワークで同じ認証パッケージを使用できます。 プロジェクト Katana とホストに依存しないミドルウェアを実行する方法の詳細については、「Katana プロジェクトではじめにする」を参照してください。

アプリケーションに認証パッケージをインストールする

  1. ソリューション エクスプローラーでプロジェクトを右クリックし、[NuGet パッケージの管理] を選択します。 Microsoft.AspNet.Identity.Owin パッケージを検索してインストールします。

    Nu Get パッケージ マネージャーの画像

  2. Microsoft.Owin.Host.SystemWeb パッケージを検索してインストールします。

    Note

    Microsoft.Aspnet.Identity.Owin パッケージには、ASP.NET Identity Core パッケージで使用される OWIN 認証ミドルウェアを管理および構成するための一連の OWIN 拡張クラスが含まれています。 Microsoft.Owin.Host.SystemWeb パッケージには、ASP.NET 要求パイプラインを使用して OWIN ベースのアプリケーションを IIS で実行できるようにする OWIN サーバーが含まれています。 詳細については、「 IIS 統合パイプラインの OWIN ミドルウェア」を参照してください。

OWIN スタートアップおよび認証構成クラスを追加する

  1. ソリューション エクスプローラーでプロジェクトを右クリックし、[追加] を選択し、[新しい項目の追加] を選択します。 検索テキスト ボックス ダイアログで、「owin」と入力します。 クラスに「Startup」という名前を付 け、[追加] を選択します。

    [新しい項目の追加] ウィンドウの画像

  2. Startup.cs ファイルで、次に示す強調表示されたコードを追加して、OWIN Cookie 認証を構成します。

    using Microsoft.AspNet.Identity;
    using Microsoft.Owin;
    using Microsoft.Owin.Security.Cookies;
    using Owin;
    
    [assembly: OwinStartup(typeof(WebFormsIdentity.Startup))]
    
    namespace WebFormsIdentity
    {
       public class Startup
       {
          public void Configuration(IAppBuilder app)
          {
             // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888
             app.UseCookieAuthentication(new CookieAuthenticationOptions
             {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Login")
             });
          }
       }
    }
    

    Note

    このクラスには、 OwinStartup OWIN スタートアップ クラスを指定するための 属性が含まれています。 すべての OWIN アプリケーションには、アプリケーション パイプラインのコンポーネントを指定するスタートアップ クラスがあります。 このモデルの詳細については、「 OWIN スタートアップ クラスの検出 」を参照してください。

ユーザーを登録およびサインインするための Web フォームを追加する

  1. Register.aspx.cs ファイルを開き、登録が成功したときにユーザーをサインインさせる次のコードを追加します。

    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.Owin.Security;
    using System;
    using System.Linq;
    using System.Web;
    
    namespace WebFormsIdentity
    {
       public partial class Register : System.Web.UI.Page
       {
          protected void CreateUser_Click(object sender, EventArgs e)
          {
             // Default UserStore constructor uses the default connection string named: DefaultConnection
             var userStore = new UserStore<IdentityUser>();
             var manager = new UserManager<IdentityUser>(userStore);
             var user = new IdentityUser() { UserName = UserName.Text };
    
             IdentityResult result = manager.Create(user, Password.Text);
    
             if (result.Succeeded)
             {
                var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                var userIdentity = manager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
                authenticationManager.SignIn(new AuthenticationProperties() { }, userIdentity);
                Response.Redirect("~/Login.aspx");
             }
             else
             {
                StatusMessage.Text = result.Errors.FirstOrDefault();
             }
          }
       }
    }
    

    Note

    • ASP.NET ID と OWIN Cookie 認証はクレーム ベースのシステムであるため、フレームワークでは、アプリ開発者がユーザーの ClaimsIdentity を生成する必要があります。 ClaimsIdentity には、ユーザーが属しているロールなど、ユーザーのすべての要求に関する情報があります。 この段階で、ユーザーの要求をさらに追加することもできます。
    • OWIN から AuthenticationManager を使用し、上記のように ClaimsIdentity を呼び出 SignIn して渡すことで、ユーザーにサインインできます。 このコードにより、ユーザーがサインインし、Cookie も生成されます。 この呼び出しは、FormsAuthentication モジュールで使用される FormAuthentication.SetAuthCookie に似ています。
  2. ソリューション エクスプローラーでプロジェクトを右クリックし、[追加]、[Web フォーム] の順に選択します。 Web フォームにログインという名前を 付けます

    新しい Web フォームを追加する画像

  3. Login.aspx ファイルの内容を次のコードに置き換えます。

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="WebFormsIdentity.Login" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
       <title></title>
    </head>
    <body style="font-family: Arial, Helvetica, sans-serif; font-size: small">
       <form id="form1" runat="server">
          <div>
             <h4 style="font-size: medium">Log In</h4>
             <hr />
             <asp:PlaceHolder runat="server" ID="LoginStatus" Visible="false">
                <p>
                   <asp:Literal runat="server" ID="StatusText" />
                </p>
             </asp:PlaceHolder>
             <asp:PlaceHolder runat="server" ID="LoginForm" Visible="false">
                <div style="margin-bottom: 10px">
                   <asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
                   <div>
                      <asp:TextBox runat="server" ID="UserName" />
                   </div>
                </div>
                <div style="margin-bottom: 10px">
                   <asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
                   <div>
                      <asp:TextBox runat="server" ID="Password" TextMode="Password" />
                   </div>
                </div>
                <div style="margin-bottom: 10px">
                   <div>
                      <asp:Button runat="server" OnClick="SignIn" Text="Log in" />
                   </div>
                </div>
             </asp:PlaceHolder>
             <asp:PlaceHolder runat="server" ID="LogoutButton" Visible="false">
                <div>
                   <div>
                      <asp:Button runat="server" OnClick="SignOut" Text="Log out" />
                   </div>
                </div>
             </asp:PlaceHolder>
          </div>
       </form>
    </body>
    </html>
    
  4. Login.aspx.cs ファイルの内容を次のように置き換えます。

    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.Owin.Security;
    using System;
    using System.Web;
    using System.Web.UI.WebControls;
    
    namespace WebFormsIdentity
    {
       public partial class Login : System.Web.UI.Page
       {
          protected void Page_Load(object sender, EventArgs e)
          {
             if (!IsPostBack)
             {
                if (User.Identity.IsAuthenticated)
                {
                   StatusText.Text = string.Format("Hello {0}!!", User.Identity.GetUserName());
                   LoginStatus.Visible = true;
                   LogoutButton.Visible = true;
                }
                else
                {
                   LoginForm.Visible = true;
                }
             }
          }
    
          protected void SignIn(object sender, EventArgs e)
          {
             var userStore = new UserStore<IdentityUser>();
             var userManager = new UserManager<IdentityUser>(userStore);
             var user = userManager.Find(UserName.Text, Password.Text);
    
             if (user != null)
             {
                var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                var userIdentity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
    
                authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, userIdentity);
                Response.Redirect("~/Login.aspx");
             }
             else
             {
                StatusText.Text = "Invalid username or password.";
                LoginStatus.Visible = true;
             }
          }
    
          protected void SignOut(object sender, EventArgs e)
          {
             var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
             authenticationManager.SignOut();
             Response.Redirect("~/Login.aspx");
          }
       }
    }
    

    Note

    • 現在の Page_Load ユーザーの状態がチェックされ、その状態に基づいてアクションが Context.User.Identity.IsAuthenticated 実行されます。 [ログインしたユーザー名の表示]: Microsoft ASP.NET Identity Framework には、System.Security.Principal.IIdentity に拡張メソッドが追加されています。これにより、ログインしているユーザーの と UserId を取得UserNameできます。 これらの拡張メソッドは、アセンブリで Microsoft.AspNet.Identity.Core 定義されます。 これらの拡張メソッドは、 HttpContext.User.Identity.Name の代わりです。
    • SignIn メソッド: This メソッドは、このサンプルの前 CreateUser_Click のメソッドを置き換え、ユーザーを正常に作成した後にサインインします。
      Microsoft OWIN Framework には、 へのIOwinContext参照をSystem.Web.HttpContext取得できる 拡張メソッドが 追加されています。 これらの拡張メソッドは、アセンブリで Microsoft.Owin.Host.SystemWeb 定義されます。 クラスは OwinContext 、現在の要求で IAuthenticationManager 使用できる認証ミドルウェア機能を表す プロパティを公開します。 ユーザーにサインインするには、OWIN から を AuthenticationManager 使用し、上記のように を呼び出 SignIn して を ClaimsIdentity 渡します。 ASP.NET ID と OWIN Cookie 認証はクレーム ベースのシステムであるため、フレームワークでは、アプリがユーザーの を ClaimsIdentity 生成する必要があります。 には ClaimsIdentity 、ユーザーが属しているロールなど、ユーザーのすべての要求に関する情報があります。 この段階でユーザーに対する要求をさらに追加することもできます。このコードにより、ユーザーがサインインし、Cookie も生成されます。 この呼び出しは、FormsAuthentication モジュールで使用される FormAuthentication.SetAuthCookie に似ています。
    • SignOut メソッド: OWIN から への参照を AuthenticationManager 取得し、 を呼び出します SignOut。 これは、FormsAuthentication モジュールで使用される FormsAuthentication.SignOut メソッドに似ています。
  5. Ctrl + F5 キーを押して、Web アプリケーションをビルドして実行します。 新しいユーザー名とパスワードを入力し、[ 登録] を選択します。

    新しい usr 登録の画像
    注: この時点で、新しいユーザーが作成され、ログインされます。

  6. [ ログアウト ] ボタンを選択します。 [ログイン] フォームにリダイレクトされます。

  7. 無効なユーザー名またはパスワードを入力し、[ ログイン ] ボタンを選択します。 メソッドは UserManager.Find null を返し、" 無効なユーザー名またはパスワード " というエラー メッセージが表示されます。

    無効なログイン試行の画像