演習 - Identity のサポートを構成する

完了

Identity は、カスタマイズしなくてもすぐに使用できます。 このユニットでは、Identity を既存の ASP.NET Core Razor Pages プロジェクトに追加します。

スターター プロジェクトを開く

推奨される GitHub codespace を使用するにはMicrosoftDocs/mslearn-secure-aspnet-core-identity リポジトリの Codespaces に移動します。 main ブランチを使用して新しい codespace を作成した後、「アプリの確認」までスキップします。

ローカル開発コンテナーを使用するには、以下の手順に従います。

  1. Visual Studio Code ウィンドウで、F1 キーを押してコマンド パレットを開きます。 [開発コンテナー:コンテナー ボリュームにリポジトリをクローンする...] を検索して選択します。

  2. 次のリポジトリ URL を入力します: https://github.com/MicrosoftDocs/mslearn-secure-aspnet-core-identitymain ブランチを選択します。 Visual Studio Code によって開発コンテナーが作成されます。 推奨される拡張機能をインストールするためのプロンプトをすべて受け入れます。

  3. アプリの確認」までスキップします。

ローカル開発環境を使用するには、以下の手順に従います。

  1. ターミナル ウィンドウで、次のコマンドを実行してスターター プロジェクトを取得します。

    git clone https://github.com/MicrosoftDocs/mslearn-secure-aspnet-core-identity
    
  2. ソース コード ディレクトリに切り替えて、Visual Studio Code を起動します。

    cd mslearn-secure-aspnet-core-identity
    code .
    

    Visual Studio Code が開きます。 推奨される拡張機能をインストールするためのプロンプトはすべて受け入れますが、プロンプトが表示されても [コンテナーで再度開く] は選択しないでください。 次の手順に進みます。

アプリを検討する

  1. プロジェクトが読み込まれたら、Ctrl+Shift+` キーを押して新しいターミナル ウィンドウを開きます。

  2. 新しいターミナル ウィンドウで、場所を RazorPagesPizza ディレクトリに設定します。

    cd RazorPagesPizza
    
  3. エクスプローラー ウィンドウで、RazorPagesPizza ディレクトリを展開してコードを表示します。 RazorPagesPizza はプロジェクト ディレクトリです。 これ以降、このモジュールで説明するすべてのパスは、この場所を基準にするものとします。

    では、アプリを実行して概要を理解することにしましょう。

  4. ターミナル ウィンドウで、プロジェクトをビルドし、アプリを実行します。

    dotnet run
    
  5. ターミナル出力に表示される URL をメモしてください。 たとえば、「 https://localhost:7192 」のように入力します。

  6. Ctrl キーを押しながら "クリック"して、その URL を選択し、ブラウザーでアプリを開きます。

    重要

    開発コンテナーをローカル Docker 内で使用している場合、コンテナー内からの SSL 証明書は、ブラウザーによって信頼されません。 Web アプリを表示するには、次のいずれかの操作を行う必要があります。

    • 証明書エラーを無視します。 Microsoft Edge を使用している場合は、[詳細設定][localhost へ移動 (非推奨)] を選択します。 詳細はブラウザーによって異なります。
    • 証明書を保存し、信頼できる証明機関に追加します。
    • コンテナー内に既存の開発証明書をインポートします。 詳細については、./devcontainer/devcontainter.json に生成されるコメントを参照してください。
  7. ブラウザーで Web アプリを探索します。 ヘッダーのリンクを使用して、次の操作を行います。

    1. [ピザ リスト]に移動する
    2. [ホーム] に戻る

    認証が要求されないことに注目してください。

  8. アプリを停止するには、ターミナル ウィンドウで、Ctrl+C キーを押します。

ASP.NET Core ID をプロジェクトに追加する

既定の ID 実装は、dotnet コマンドライン ツールを使用して追加できます。

  1. ASP.NET Core コード スキャフォールディングをインストールします。

    dotnet tool install dotnet-aspnet-codegenerator --version 8.0.* --global
    

    スキャフォールディングは、以下の .NET ツールです。

    • プロジェクトに既定の Identity コンポーネントを追加するために使われます。
    • 次のユニットで Identity UI コンポーネントをカスタマイズできるようにします。
    • このモジュールでは dotnet aspnet-codegenerator を介して呼び出されます。
  2. 次の NuGet パッケージをプロジェクトに追加します。

    dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design --version 8.0.*
    dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore --version 8.0.*
    dotnet add package Microsoft.AspNetCore.Identity.UI --version 8.0.*
    dotnet add package Microsoft.EntityFrameworkCore.Design --version 8.0.*
    dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 8.0.*
    dotnet add package Microsoft.EntityFrameworkCore.Tools --version 8.0.*
    

    これらのパッケージによって、スキャフォールディングで使用されるコード生成テンプレートと依存関係がインストールされます。

    ヒント

    使用可能なジェネレーターを表示するには:

    • コマンド シェルで dotnet aspnet-codegenerator -h を実行します。
    • Visual Studio を使用しているときは、ソリューション エクスプローラーでプロジェクトを右クリックし、[追加]>[新規スキャフォールディング アイテム] を選択します。
  3. スキャフォールディングを使用して、プロジェクトに既定の Identity コンポーネントを追加します。 ターミナルで次のコマンドを実行します。

    dotnet aspnet-codegenerator identity --useDefaultUI --dbContext RazorPagesPizzaAuth --userClass RazorPagesPizzaUser
    

    上記のコマンドでは次のことが行われます。

    • プロジェクトへの Identity フレームワークの追加には、identity として識別されるジェネレーターが使用されます。
    • --useDefaultUI オプションで、既定の UI 要素を含む Razor クラス ライブラリ (RCL) を使うことを指示します。 コンポーネントのスタイルを設定するには、Bootstrap が使われます。
    • --dbContext オプションは、生成する EF Core データ コンテキスト クラスの名前を指定します。
    • --userClass オプションは、生成するユーザー クラスの名前を指定します。 既定のユーザー クラスは IdentityUser ですが、ユーザー クラスは後のユニットで拡張されるため、RazorPagesPizzaUser という名前のカスタム ユーザー クラスが指定されます。 RazorPagesPizzaUser クラスは IdentityUser から派生しています。

    次の Areas ディレクトリ構造が RazorPagesPizza ディレクトリに表示されます。

    • Areas
      • Identity (Areas と同じ行に表示されます)
        • Data
          • RazorPagesPizzaAuth.cs
          • RazorPagesPizzaUser.cs
        • Pages
          • _ValidationScriptsPartial.cshtml
          • _ViewStart.cshtml

    ヒント

    Areas ディレクトリがエクスプローラー ウィンドウに自動的に表示されない場合は、エクスプローラー ウィンドウの MSLEARN-SECURE-ASPNET-CORE-IDENTITY ヘッダーの [エクスプローラーを最新表示する] を選択します。

    Areas では、ASP.NET Core Web アプリをより小さい機能グループに分割する手段が提供されます。

    また、スキャフォールディングによって、以下の強調表示した変更が Program.cs に加えられ、読みやすいように再フォーマットされました。

    using Microsoft.AspNetCore.Identity;
    using Microsoft.EntityFrameworkCore;
    using RazorPagesPizza.Areas.Identity.Data;
    var builder = WebApplication.CreateBuilder(args);
    var connectionString = builder.Configuration.GetConnectionString("RazorPagesPizzaAuthConnection") 
        ?? throw new InvalidOperationException("Connection string 'RazorPagesPizzaAuthConnection' not found.");
    
    builder.Services.AddDbContext<RazorPagesPizzaAuth>(options => options.UseSqlServer(connectionString));
    
    builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<RazorPagesPizzaAuth>();
    
    // Add services to the container.
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapRazorPages();
    
    app.Run();
    

    上のコードでは以下の操作が行われます。

    • RazorPagesPizzaAuthConnection 接続文字列は、appsettings.json から読み取られます。
    • RazorPagesPizzaAuthという名前の EF Core データ コンテキスト クラスは、接続文字列を使用して構成されます。
    • Identity サービスが登録されます。これには、既定の UI、トークン プロバイダー、および Cookie ベースの認証が含まれます。
      • .AddDefaultIdentity<IdentityUser> は、ID サービスに対して、既定のユーザー モデルを使用するように指示します。
      • ラムダ式 options => options.SignIn.RequireConfirmedAccount = true は、ユーザーが自分のメール アカウントを確認する必要があることを指定します。
      • .AddEntityFrameworkStores<RazorPagesPizzaAuth>() は、ID で、データベースに既定の Entity Framework Core ストアを使用することを指定します。 RazorPagesPizzaAuth DbContext クラスが使われます。

データベース接続を構成する

appsettings.json 内の ConnectionStrings セクションは、次の JSON のようになります。

"ConnectionStrings": {
    "RazorPagesPizzaAuthConnection": "Server=(localdb)\\mssqllocaldb;Database=RazorPagesPizza;Trusted_Connection=True;MultipleActiveResultSets=true"
}

この接続文字列は、既定で SQL Server Express LocalDB のインスタンスを指します。 ローカルで開発している場合は、何も行わないでください。 これが正しい接続文字列です。

codespace または開発コンテナーにおいて、接続文字列が正しくありません。 codespace または開発コンテナーを使用している場合、接続文字列を次のように変更する必要があります。 必ず変更内容を保存してください。

"ConnectionStrings": {
    "RazorPagesPizzaAuthConnection": "Data Source=localhost;Initial Catalog=RazorPagesPizza;Integrated Security=False;User Id=sa;Password=P@ssw0rd;MultipleActiveResultSets=True;Encrypt=False"
}

これにより、接続文字列が更新され、コンテナー内の SQL Server のインスタンスに接続されるようになります。

データベースを更新する

接続文字列を確認したので、移行を生成して実行し、データベースを構築することができます。

  1. 次のコマンドを実行して、アプリをビルドします。

    dotnet build
    

    ビルドは警告なしで成功します。 ビルドに失敗した場合は、出力でトラブルシューティング情報を確認してください。

  2. Entity Framework Core 移行ツールをインストールします。

    dotnet tool install dotnet-ef --version 8.0.* --global
    

    移行ツールは、次のような .NET ツールです。

    • Identity エンティティ モデルをサポートするデータベースを作成および更新するための、移行と呼ばれるコードを生成します。
    • 既存のデータベースに対して移行を実行します。
    • このモジュールでは dotnet ef を介して呼び出されます。
  3. データベースを更新するには、EF Core の移行を作成して実行します。

    dotnet ef migrations add CreateIdentitySchema
    dotnet ef database update
    

    CreateIdentitySchema EF Core の移行では、データ定義言語 (DDL) の変更スクリプトを適用して、Identity をサポートするテーブルを作成しました。 たとえば、次の出力は、移行によって生成される CREATE TABLE ステートメントを示しています。

    info: Microsoft.EntityFrameworkCore.Database.Command[20101]
          Executed DbCommand (98ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
          CREATE TABLE [AspNetUsers] (
              [Id] nvarchar(450) NOT NULL,
              [UserName] nvarchar(256) NULL,
              [NormalizedUserName] nvarchar(256) NULL,
              [Email] nvarchar(256) NULL,
              [NormalizedEmail] nvarchar(256) NULL,
              [EmailConfirmed] bit NOT NULL,
              [PasswordHash] nvarchar(max) NULL,
              [SecurityStamp] nvarchar(max) NULL,
              [ConcurrencyStamp] nvarchar(max) NULL,
              [PhoneNumber] nvarchar(max) NULL,
              [PhoneNumberConfirmed] bit NOT NULL,
              [TwoFactorEnabled] bit NOT NULL,
              [LockoutEnd] datetimeoffset NULL,
              [LockoutEnabled] bit NOT NULL,
              [AccessFailedCount] int NOT NULL,
              CONSTRAINT [PK_AspNetUsers] PRIMARY KEY ([Id])
          );
    

    ヒント

    ef コマンドは、LocalDb がサポートされていないことに関するエラーをスローしましたか? 「データベース接続を構成する」セクションの説明に従って接続文字列を設定したことを確認します。

  4. SQL Server 拡張機能は、推奨される拡張機能を受け入れたときに、必要に応じて Visual Studio Code に追加されています。 Ctrl+Alt+D キーを押して、SQL Server ウィンドウに切り替えます。

  5. 既存のデータベース接続の下にあるノードを展開します。 Databases ノード、RazorPagesPizza ノードの順に展開し、最後に Tables ノードを展開します。 テーブルの一覧に注目してください。 これにより、移行が成功したことを確認できます。

    新しく作成されたテーブルがある RazorPagesPizza データベース。

    Note

    上の画像は、SQL Server Express LocalDB の使用例を示しています。 .devcontainer を使用している場合、接続は mssql-container という名前です。

[エクスプローラー] ペインに戻ります。 Pages/Shared/_Layout.cshtml で、コメント @* Add the _LoginPartial partial view *@ を以下に置き換えます。

<partial name="_LoginPartial" />

上記のマークアップでは、既定のレイアウトを使用するすべてのページのヘッダー内に _LoginPartial 部分ビューがレンダリングされます。 Identity スキャフォールディングによって _LoginPartial が追加されました。 この部分ビューでは、ユーザーがサインインしていない場合に、[ログイン] および [登録] リンクがユーザーに表示されます。

ID 機能をテストする

既定の ID 実装を追加する場合、必要なのはこれだけです。 では、テストを始めましょう。

  1. すべての変更を必ず保存してください。

  2. ターミナル ウィンドウで、プロジェクトをビルドし、アプリを実行します。

    dotnet run
    
  3. 前と同じように、ブラウザーでアプリに移動します。

  4. アプリのヘッダーの [登録] (Register) リンクを選びます。 フォームに入力して、新しいアカウントを作成します。

    [登録の確認] ページが表示されます。 アプリは確認メールを送信するように構成されていないため、このページに確認リンクが表示されます。

  5. 確認リンクを選びます。 確認メッセージが表示されます。

  6. アプリのヘッダーで [ログイン] (Login) リンクを選んでサインインします。

    正常にサインインした後:

    • ホーム ページにリダイレクトされます。
    • アプリのヘッダーに、[Hello <メール アドレス>!] (こんにちは <メール アドレス>!)[Logout] (ログアウト) リンクが表示されます。
    • .AspNetCore.Identity.Application という名前の Cookie が作成されます。 Identity では、Cookie ベースの認証を使用してユーザー セッションが保持されます。
  7. アプリのヘッダーで [Logout] (ログアウト) リンクを選びます。

    ログアウトが正常に完了すると、.AspNetCore.Identity.Application Cookie が削除されてユーザー セッションが終了されます。

  8. アプリを停止するには、ターミナル ウィンドウで、Ctrl+C キーを押します。

まとめ

このユニットでは、既定の ID 実装を既存の Web アプリに追加しました。 次のユニットでは、ID の拡張とカスタマイズについて学習します。