次の方法で共有


ASP.NET Core プロジェクトでの Identity のスキャフォールディング

作成者: Rick Anderson

BlazorIdentity スキャフォールディング

ASP.NET Core の Identity スキャフォールディングにより、ASP.NET Core の Identity に Blazor Web Apps と Blazor Server アプリが追加されます。 スキャフォールディングによって IdentityRazor コンポーネントがアプリに追加されたら、アプリの要件に合わせてコンポーネントをカスタマイズできます。

スキャフォールディング ツールは、Identity をアプリにスキャフォールディングするために必要な C# コードを生成しますが、プロセスを完了するには、Entity Framework (EF) Core データベースの移行を使用してプロジェクトのデータベースを更新する必要があります。 この記事では、データベースを移行するために必要な手順について説明します。

Identity スキャフォールディングを実行した後、変更内容を検査します。 GitHub または、変更を元に戻す機能によりファイルの変更を表示する別のソース管理システムを使用することをお勧めします。

サービスは、Identity で 2 要素認証 (2FA)アカウントの確認とパスワードの回復、その他のセキュリティ機能を使用する場合に必要です。 サービスまたはサービス スタブは、Identity のスキャフォールディング時に生成されません。 これらの機能を有効にするサービスは、手動で追加する必要があります。

Razor ページと MVC Identity のスキャフォールディング

ASP.NET Core では、ASP.NET Core IdentityRazor クラス ライブラリ (RCL) として提供しています。 Identity を含むアプリケーションでは、Identity RCL に含まれるソース コードを選択的に追加するようにスキャフォールディングを適用できます。 コードを変更して動作を変更できるように、ソース コードを生成できます。 たとえば、登録で使用するコードを生成するようにスキャフォルダーに指示できます。 カスタマイズされた Identity コードは、Identity RCL によって提供される既定の実装をオーバーライドします。 UI を完全に制御し、既定の RCL を使用しないようにするには、「完全な Identity UI ソースを作成する」セクションを参照してください。

認証を含まないアプリケーションでは、RCL Identity パッケージを追加するようにスキャフォールディングを適用できます。 生成される Identity コードの選択オプションがあります。

スキャフォールディングによって、必要なコードの大部分が生成されますが、プロセスを完了するにはプロジェクトを更新する必要があります。 このドキュメントでは、Identity スキャフォールディングの更新を完了するために必要な手順について説明します。

ファイルの差分が表示され、変更を取り消すことができるソース管理システムを使用することをお勧めします。 Identity スキャフォールディングを実行した後、変更内容を検査します。

サービスは、Identity で 2 要素認証アカウントの確認とパスワードの回復、およびその他のセキュリティ機能を使用する場合に必要です。 サービスまたはサービス スタブは、Identity のスキャフォールディング時に生成されません。 これらの機能を有効にするサービスは、手動で追加する必要があります。 たとえば、電子メール確認の要求に関する記事をご覧ください。

通常は、個別のアカウントで作成されたアプリでは、新しいデータ コンテキストを作成 "しない" ようにする必要があります。

Identity を Blazor プロジェクトにスキャフォールディングする

このセクションは Blazor Web Apps と Blazor Server アプリに適用されます。

Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Blazor Identity] を選択します。 追加 ボタンを選択します。
  • [BlazorIdentity の追加] ダイアログで、次のことを行います。
    • データベース コンテキスト クラス (DbContext クラス) を選択するか、プラス (+) ボタンで追加します。
    • データベース プロバイダー (Database プロバイダー) を選択します。既定では SQL Server です。
    • ユーザー クラス (User クラス) を選択するか、プラス (+) ボタンで追加します。
    • 追加 ボタンを選択します。

生成された Identity データベース コードには、EF Core Migrations が必要です。 次の手順では、データベースに移行を作成して適用する方法について説明します。

Visual Studio Connected Services で EF Core 移行を追加し、データベースを更新します。

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[移行の追加] を選択します。

移行には、その移行を説明する名前である移行の名前 (CreateIdentitySchema など) を付けます。 データベース コンテキストが [DbContext クラス名] フィールドに読み込まれるのを待ちます。これは数秒かかる場合があります。 [完了] を選択して移行を作成します。

操作の完了後、[閉じる] ボタンを選択します。

省略記号 (...) をもう一度選択し、次に [データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

データベースの更新コマンドは、スキャフォールディングによって作成された移行コード ファイルに適用されていない Up メソッドの移行を行います。 この場合、コマンドは Migrations/{TIME STAMP}_{MIGRATION NAME}.cs ファイル内の Up メソッドを実行し、Identity テーブル、制約、インデックスを作成します。 {TIME STAMP} プレースホルダーはタイム スタンプであり、{MIGRATION NAME} プレースホルダーは移行名です。

クライアント側の Blazor アプリ (スタンドアロン Blazor WebAssembly)

クライアント側の Blazor アプリ (スタンドアロン Blazor WebAssembly)_ では独自の Identity UI アプローチを使用するため、ASP.NET Core Identity のスキャフォールディングを使用することはできません。

詳細については、Blazor セキュリティと Identity に関する記事をご覧ください。

Razor プロジェクトに既存の認可なしで Identity をスキャフォールディングする

Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet パッケージをインストールします。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。


Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

移行、UseAuthentication、レイアウト

生成された Identity データベース コードには、Entity Framework (EF) Core 移行が必要です。 Identity スキーマを作成するための移行が作成されておらず、データベースに適用されていない場合は、移行を作成してデータベースを更新します。

Visual Studio Connected Services で EF Core 移行を追加し、データベースを更新します。

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[移行の追加] を選択します。

移行には、その移行を説明する名前である移行の名前 (CreateIdentitySchema など) を付けます。 データベース コンテキストが [DbContext クラス名] フィールドに読み込まれるのを待ちます。これは数秒かかる場合があります。 [完了] を選択して移行を作成します。

操作の完了後、[閉じる] ボタンを選択します。

省略記号 (...) をもう一度選択し、次に [データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

データベースの更新コマンドは、スキャフォールディングによって作成された移行コード ファイルに適用されていない Up メソッドの移行を行います。 この場合、コマンドは Migrations/{TIME STAMP}_{MIGRATION NAME}.cs ファイル内の Up メソッドを実行し、Identity テーブル、制約、インデックスを作成します。 {TIME STAMP} プレースホルダーはタイム スタンプであり、{MIGRATION NAME} プレースホルダーは移行名です。

Identity スキーマが既に作成されているが、データベースに適用されていない場合は、データベースを更新するコマンドのみを実行する必要があります:

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

次のコマンドを使用して、 Identity スキーマのアプリケーションを確認できます。 コマンドの出力には、データベースに適用される移行を示す "applied" 列が含まれています。

Visual Studio パッケージ マネージャー コンソールの場合は、Get-Migration を実行します:

Get-Migration

複数のデータベース コンテキストが存在する場合は、-Context パラメーターを使用してコンテキストを指定します。

レイアウトの変更

省略可能: ログイン部分 (_LoginPartial) をレイアウト ファイルに追加します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRPnoAuth2Auth</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/WebRPnoAuth2Auth.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">WebRPnoAuth2Auth</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                        </li>
                    </ul>
                    <partial name="_LoginPartial" />
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2021 - WebRPnoAuth2Auth - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

Razor プロジェクトに認可ありで Identity をスキャフォールディングする

Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet パッケージをインストールします。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。


Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

MVC プロジェクトに既存の認可なしで Identity をスキャフォールディングする

Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet パッケージをインストールします。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。


Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

省略可能: ログイン部分 (_LoginPartial) を Views/Shared/_Layout.cshtml ファイルに追加します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRPnoAuth2Auth</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/WebRPnoAuth2Auth.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">WebRPnoAuth2Auth</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                        </li>
                    </ul>
                    <partial name="_LoginPartial" />
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2021 - WebRPnoAuth2Auth - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

生成された Identity データベース コードには、Entity Framework (EF) Core 移行が必要です。 Identity スキーマを作成するための移行が作成されておらず、データベースに適用されていない場合は、移行を作成してデータベースを更新します。

Visual Studio Connected Services で EF Core 移行を追加し、データベースを更新します。

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[移行の追加] を選択します。

移行には、その移行を説明する名前である移行の名前 (CreateIdentitySchema など) を付けます。 データベース コンテキストが [DbContext クラス名] フィールドに読み込まれるのを待ちます。これは数秒かかる場合があります。 [完了] を選択して移行を作成します。

操作の完了後、[閉じる] ボタンを選択します。

省略記号 (...) をもう一度選択し、次に [データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

データベースの更新コマンドは、スキャフォールディングによって作成された移行コード ファイルに適用されていない Up メソッドの移行を行います。 この場合、コマンドは Migrations/{TIME STAMP}_{MIGRATION NAME}.cs ファイル内の Up メソッドを実行し、Identity テーブル、制約、インデックスを作成します。 {TIME STAMP} プレースホルダーはタイム スタンプであり、{MIGRATION NAME} プレースホルダーは移行名です。

Identity スキーマが既に作成されているが、データベースに適用されていない場合は、データベースを更新するコマンドのみを実行する必要があります:

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

次のコマンドを使用して、 Identity スキーマのアプリケーションを確認できます。 コマンドの出力には、データベースに適用される移行を示す "applied" 列が含まれています。

Visual Studio パッケージ マネージャー コンソールの場合は、Get-Migration を実行します:

Get-Migration

複数のデータベース コンテキストが存在する場合は、-Context パラメーターを使用してコンテキストを指定します。

次の強調表示されたコードに示すように、MapRazorPagesProgram.cs に追加します。

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebMVCauth.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();

app.Run();

MVC プロジェクトに認可ありで Identity をスキャフォールディングする

Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet パッケージをインストールします。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。


Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

完全な Identity UI ソースを作成する

Identity UI の完全な制御を維持するには、Identity スキャフォールディングを実行し、[すべてのファイルをオーバーライド] を選択します。

パスワードの構成

PasswordOptionsStartup.ConfigureServices で構成されている場合、[StringLength] 属性の構成が、スキャフォールディングされる Identity ページの Password プロパティに必要になることがあります。 InputModel Password プロパティは、次のファイルにあります。

  • Areas/Identity/Pages/Account/Register.cshtml.cs
  • Areas/Identity/Pages/Account/ResetPassword.cshtml.cs

ページを無効にする

このセクションでは、登録ページを無効にする方法を示しますが、この方法を使用して任意のページを無効にできます。

ユーザー登録を無効にするには、次のようにします。

  • Identity をスキャフォールディングします。 Account.Register、Account.Login、Account.RegisterConfirmation を含めます。 次に例を示します。

    dotnet aspnet-codegenerator identity -dc RPauth.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.RegisterConfirmation"
    
  • Areas/Identity/Pages/Account/Register.cshtml.cs を更新して、ユーザーがこのエンドポイントから登録できないようにします。

    public class RegisterModel : PageModel
    {
        public IActionResult OnGet()
        {
            return RedirectToPage("Login");
        }
    
        public IActionResult OnPost()
        {
            return RedirectToPage("Login");
        }
    }
    
  • 前の変更と一致するように Areas/Identity/Pages/Account/Register.cshtml を更新します。

    @page
    @model RegisterModel
    @{
        ViewData["Title"] = "Go to Login";
    }
    
    <h1>@ViewData["Title"]</h1>
    
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
    
  • コメント アウトするか Areas/Identity/Pages/Account/Login.cshtml から登録リンクを削除します

    @*
    <p>
        <a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
    </p>
    *@
    
  • Areas/Identity/Pages/Account/RegisterConfirmation ページを更新します。

    • cshtml ファイルからコードとリンクを削除します。
    • PageModel から確認コードを削除します。
    [AllowAnonymous]
      public class RegisterConfirmationModel : PageModel
      {
          public IActionResult OnGet()
          {  
              return Page();
          }
      }
    

別のアプリを使用してユーザーを追加する

Web アプリの外部にユーザーを追加するメカニズムを提供します。 ユーザーを追加するオプションには次のものがあります。

  • 専用管理者の Web アプリ。
  • コンソール アプリ。

次のコードは、ユーザーを追加する 1 つの方法の概要を示しています。

  • ユーザーの一覧がメモリに読み込まれる。
  • ユーザーごとに強力な一意のパスワードが生成される。
  • ユーザーが Identity データベースに追加される。
  • ユーザーに通知され、パスワードを変更するように指示される。
public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();

        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                var context = services.GetRequiredService<AppDbCntx>();
                context.Database.Migrate();

                var config = host.Services.GetRequiredService<IConfiguration>();
                var userList = config.GetSection("userList").Get<List<string>>();

                SeedData.Initialize(services, userList).Wait();
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred adding users.");
            }
        }

        host.Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

次のコードは、ユーザー追加の概要を示しています。


public static async Task Initialize(IServiceProvider serviceProvider,
                                    List<string> userList)
{
    var userManager = serviceProvider.GetService<UserManager<IdentityUser>>();

    foreach (var userName in userList)
    {
        var userPassword = GenerateSecurePassword();
        var userId = await EnsureUser(userManager, userName, userPassword);

        NotifyUser(userName, userPassword);
    }
}

private static async Task<string> EnsureUser(UserManager<IdentityUser> userManager,
                                             string userName, string userPassword)
{
    var user = await userManager.FindByNameAsync(userName);

    if (user == null)
    {
        user = new IdentityUser(userName)
        {
            EmailConfirmed = true
        };
        await userManager.CreateAsync(user, userPassword);
    }

    return user.Id;
}

実稼働シナリオでも、同様のアプローチに従うことができます。

静的 Identity アセットを発行しないようにする

静的 Identity アセットを Web ルートに発行しないようにするには、「ASP.NET Core の Identity の概要」を参照してください。

ASP.NET Core では、ASP.NET Core IdentityRazor クラス ライブラリ (RCL) として提供しています。 Identity を含むアプリケーションでは、Identity RCL に含まれるソース コードを選択的に追加するようにスキャフォールディングを適用できます。 コードを変更して動作を変更できるように、ソース コードを生成できます。 たとえば、登録で使用するコードを生成するようにスキャフォルダーに指示できます。 生成されたコードは、Identity RCL の同じコードよりも優先されます。 UI を完全に制御し、既定の RCL を使用しないようにするには、「完全な Identity UI ソースを作成する」セクションを参照してください。

認証を含まないアプリケーションでは、RCL Identity パッケージを追加するようにスキャフォールディングを適用できます。 生成される Identity コードの選択オプションがあります。

スキャフォールディングによって、必要なコードの大部分が生成されますが、プロセスを完了するにはプロジェクトを更新する必要があります。 このドキュメントでは、Identity スキャフォールディングの更新を完了するために必要な手順について説明します。

ファイルの差分が表示され、変更を取り消すことができるソース管理システムを使用することをお勧めします。 Identity スキャフォールディングを実行した後、変更内容を検査します。

サービスは、Identity で 2 要素認証アカウントの確認とパスワードの回復、およびその他のセキュリティ機能を使用する場合に必要です。 サービスまたはサービス スタブは、Identity のスキャフォールディング時に生成されません。 これらの機能を有効にするサービスは、手動で追加する必要があります。 たとえば、電子メール確認の要求に関する記事をご覧ください。

通常は、個別のアカウントで作成されたアプリでは、新しいデータ コンテキストを作成 "しない" ようにする必要があります。

Razor プロジェクトに既存の認可なしで Identity をスキャフォールディングする

Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet パッケージをインストールします。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。


Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

移行、UseAuthentication、レイアウト

生成された Identity データベース コードには、Entity Framework (EF) Core 移行が必要です。 Identity スキーマを作成するための移行が作成されておらず、データベースに適用されていない場合は、移行を作成してデータベースを更新します。

Visual Studio Connected Services で EF Core 移行を追加し、データベースを更新します。

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[移行の追加] を選択します。

移行には、その移行を説明する名前である移行の名前 (CreateIdentitySchema など) を付けます。 データベース コンテキストが [DbContext クラス名] フィールドに読み込まれるのを待ちます。これは数秒かかる場合があります。 [完了] を選択して移行を作成します。

操作の完了後、[閉じる] ボタンを選択します。

省略記号 (...) をもう一度選択し、次に [データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

データベースの更新コマンドは、スキャフォールディングによって作成された移行コード ファイルに適用されていない Up メソッドの移行を行います。 この場合、コマンドは Migrations/{TIME STAMP}_{MIGRATION NAME}.cs ファイル内の Up メソッドを実行し、Identity テーブル、制約、インデックスを作成します。 {TIME STAMP} プレースホルダーはタイム スタンプであり、{MIGRATION NAME} プレースホルダーは移行名です。

Identity スキーマが既に作成されているが、データベースに適用されていない場合は、データベースを更新するコマンドのみを実行する必要があります:

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

次のコマンドを使用して、 Identity スキーマのアプリケーションを確認できます。 コマンドの出力には、データベースに適用される移行を示す "applied" 列が含まれています。

Visual Studio パッケージ マネージャー コンソールの場合は、Get-Migration を実行します:

Get-Migration

複数のデータベース コンテキストが存在する場合は、-Context パラメーターを使用してコンテキストを指定します。

レイアウトの変更

省略可能: ログイン部分 (_LoginPartial) をレイアウト ファイルに追加します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRPnoAuth2Auth</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/WebRPnoAuth2Auth.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">WebRPnoAuth2Auth</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                        </li>
                    </ul>
                    <partial name="_LoginPartial" />
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2021 - WebRPnoAuth2Auth - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

Razor プロジェクトに認可ありで Identity をスキャフォールディングする

Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet パッケージをインストールします。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。


Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

MVC プロジェクトに既存の認可なしで Identity をスキャフォールディングする

Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet パッケージをインストールします。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。


Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

省略可能: ログイン部分 (_LoginPartial) を Views/Shared/_Layout.cshtml ファイルに追加します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRPnoAuth2Auth</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/WebRPnoAuth2Auth.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">WebRPnoAuth2Auth</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                        </li>
                    </ul>
                    <partial name="_LoginPartial" />
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2021 - WebRPnoAuth2Auth - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

生成された Identity データベース コードには、Entity Framework (EF) Core 移行が必要です。 Identity スキーマを作成するための移行が作成されておらず、データベースに適用されていない場合は、移行を作成してデータベースを更新します。

Visual Studio Connected Services で EF Core 移行を追加し、データベースを更新します。

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[移行の追加] を選択します。

移行には、その移行を説明する名前である移行の名前 (CreateIdentitySchema など) を付けます。 データベース コンテキストが [DbContext クラス名] フィールドに読み込まれるのを待ちます。これは数秒かかる場合があります。 [完了] を選択して移行を作成します。

操作の完了後、[閉じる] ボタンを選択します。

省略記号 (...) をもう一度選択し、次に [データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

データベースの更新コマンドは、スキャフォールディングによって作成された移行コード ファイルに適用されていない Up メソッドの移行を行います。 この場合、コマンドは Migrations/{TIME STAMP}_{MIGRATION NAME}.cs ファイル内の Up メソッドを実行し、Identity テーブル、制約、インデックスを作成します。 {TIME STAMP} プレースホルダーはタイム スタンプであり、{MIGRATION NAME} プレースホルダーは移行名です。

Identity スキーマが既に作成されているが、データベースに適用されていない場合は、データベースを更新するコマンドのみを実行する必要があります:

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

次のコマンドを使用して、 Identity スキーマのアプリケーションを確認できます。 コマンドの出力には、データベースに適用される移行を示す "applied" 列が含まれています。

Visual Studio パッケージ マネージャー コンソールの場合は、Get-Migration を実行します:

Get-Migration

複数のデータベース コンテキストが存在する場合は、-Context パラメーターを使用してコンテキストを指定します。

次の強調表示されたコードに示すように、MapRazorPagesProgram.cs に追加します。

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebMVCauth.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();

app.Run();

MVC プロジェクトに認可ありで Identity をスキャフォールディングする

Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet パッケージをインストールします。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。


Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

承認を使用してサーバーサイド Blazor アプリに Identity をスキャフォールディングする

Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet パッケージをインストールします。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。


Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

移行

生成された Identity データベース コードには、Entity Framework (EF) Core 移行が必要です。 Identity スキーマを作成するための移行が作成されておらず、データベースに適用されていない場合は、移行を作成してデータベースを更新します。

Visual Studio Connected Services で EF Core 移行を追加し、データベースを更新します。

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[移行の追加] を選択します。

移行には、その移行を説明する名前である移行の名前 (CreateIdentitySchema など) を付けます。 データベース コンテキストが [DbContext クラス名] フィールドに読み込まれるのを待ちます。これは数秒かかる場合があります。 [完了] を選択して移行を作成します。

操作の完了後、[閉じる] ボタンを選択します。

省略記号 (...) をもう一度選択し、次に [データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

データベースの更新コマンドは、スキャフォールディングによって作成された移行コード ファイルに適用されていない Up メソッドの移行を行います。 この場合、コマンドは Migrations/{TIME STAMP}_{MIGRATION NAME}.cs ファイル内の Up メソッドを実行し、Identity テーブル、制約、インデックスを作成します。 {TIME STAMP} プレースホルダーはタイム スタンプであり、{MIGRATION NAME} プレースホルダーは移行名です。

Identity スキーマが既に作成されているが、データベースに適用されていない場合は、データベースを更新するコマンドのみを実行する必要があります:

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

次のコマンドを使用して、 Identity スキーマのアプリケーションを確認できます。 コマンドの出力には、データベースに適用される移行を示す "applied" 列が含まれています。

Visual Studio パッケージ マネージャー コンソールの場合は、Get-Migration を実行します:

Get-Migration

複数のデータベース コンテキストが存在する場合は、-Context パラメーターを使用してコンテキストを指定します。

認証エンドポイントをスタイル設定する

サーバーサイド Blazor アプリでは RazorPagesIdentity ページが使用されているため、訪問者が Identity ページとコンポーネント間を移動すると、UI のスタイルが変わります。 調和していないスタイルに対処するには、次の 2 つの選択肢があります。

カスタム Identity コンポーネント

ASP.NET Core Identity は、要求と応答の HTTP 通信のコンテキストで動作するように設計されています。これは、Blazor アプリの主要なクライアント/サーバー通信モデルではありません。 ユーザー管理に ASP.NET Core Identity を使用する ASP.NET Core アプリでは、ユーザー登録、ログイン、ログアウト、その他のユーザー管理タスクなど、Identity 関連の UI 用に、Razor コンポーネントではなく Razor Pages を使用する必要があります。

SignInManager<TUser>UserManager<TUser> は Razor コンポーネントではサポートされていないため、Web API を使って、サーバー側 Identity 対応 ASP.NET Core アプリを介して Razor コンポーネントから Identity アクションを管理することをお勧めします。 Blazor アプリ用の Web API を作成するためのガイダンスについては、ASP.NET Core Blazor アプリから Web API を呼び出す方法に関する記事を参照してください。

Razor Pages の代わりに Identity に対して Razor コンポーネントを使用する方法の 1 つは、独自のカスタム IdentityRazor コンポーネントを作成することですが、Microsoft ではこの方法を推奨しておらず、サポートもしていません。 その他のコンテキストについては、以下のディスカッションを参照してください。 以下のディスカッションにおいて、イシュー コメントのコード例と、Microsoft 以外の GitHub リポジトリにクロスリンクされているコード例は、Microsoft ではサポートされていませんが、一部の開発者にとっては役立つかもしれません。

カスタム IdentityRazor コンポーネントを作成したい場合や、サードパーティの Razor コンポーネントを探している場合のさらなるサポートについては、次のリソースをお勧めします。

Blazor アプリのスタイルでカスタム レイアウトを使用する

Identity ページのレイアウトとスタイルを変更して、既定の Blazor テーマと似たようなスタイルを使用するページを生成できます。 この方法については、ドキュメントでは説明しません。

クライアントサイド Blazor アプリ

クライアント側の Blazor アプリでは独自の Identity UI アプローチを使用し、ASP.NET Core Identity スキャフォールディングを使用することはできません。 ホストされた Blazor ソリューションのサーバー側の ASP.NET Core アプリは、この記事の Razor Pages/MVC ガイダンスに従うことができ、Identity をサポートする他の種類の ASP.NET Core アプリと同様に構成します。

Blazor フレームワークには、Razor コンポーネント バージョンの Identity UI ページは含まれていません。 Identity UI Razor コンポーネントは、カスタムで作成するか、サポートされていないサードパーティのソースから取得できます。

詳細については、Blazor セキュリティと Identity に関する記事をご覧ください。

完全な Identity UI ソースを作成する

Identity UI の完全な制御を維持するには、Identity スキャフォールディングを実行し、[すべてのファイルをオーバーライド] を選択します。

パスワードの構成

PasswordOptionsStartup.ConfigureServices で構成されている場合、[StringLength] 属性の構成が、スキャフォールディングされる Identity ページの Password プロパティに必要になることがあります。 InputModel Password プロパティは、次のファイルにあります。

  • Areas/Identity/Pages/Account/Register.cshtml.cs
  • Areas/Identity/Pages/Account/ResetPassword.cshtml.cs

ページを無効にする

このセクションでは、登録ページを無効にする方法を示しますが、この方法を使用して任意のページを無効にできます。

ユーザー登録を無効にするには、次のようにします。

  • Identity をスキャフォールディングします。 Account.Register、Account.Login、Account.RegisterConfirmation を含めます。 次に例を示します。

    dotnet aspnet-codegenerator identity -dc RPauth.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.RegisterConfirmation"
    
  • Areas/Identity/Pages/Account/Register.cshtml.cs を更新して、ユーザーがこのエンドポイントから登録できないようにします。

    public class RegisterModel : PageModel
    {
        public IActionResult OnGet()
        {
            return RedirectToPage("Login");
        }
    
        public IActionResult OnPost()
        {
            return RedirectToPage("Login");
        }
    }
    
  • 前の変更と一致するように Areas/Identity/Pages/Account/Register.cshtml を更新します。

    @page
    @model RegisterModel
    @{
        ViewData["Title"] = "Go to Login";
    }
    
    <h1>@ViewData["Title"]</h1>
    
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
    
  • コメント アウトするか Areas/Identity/Pages/Account/Login.cshtml から登録リンクを削除します

    @*
    <p>
        <a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
    </p>
    *@
    
  • Areas/Identity/Pages/Account/RegisterConfirmation ページを更新します。

    • cshtml ファイルからコードとリンクを削除します。
    • PageModel から確認コードを削除します。
    [AllowAnonymous]
      public class RegisterConfirmationModel : PageModel
      {
          public IActionResult OnGet()
          {  
              return Page();
          }
      }
    

別のアプリを使用してユーザーを追加する

Web アプリの外部にユーザーを追加するメカニズムを提供します。 ユーザーを追加するオプションには次のものがあります。

  • 専用管理者の Web アプリ。
  • コンソール アプリ。

次のコードは、ユーザーを追加する 1 つの方法の概要を示しています。

  • ユーザーの一覧がメモリに読み込まれる。
  • ユーザーごとに強力な一意のパスワードが生成される。
  • ユーザーが Identity データベースに追加される。
  • ユーザーに通知され、パスワードを変更するように指示される。
public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();

        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                var context = services.GetRequiredService<AppDbCntx>();
                context.Database.Migrate();

                var config = host.Services.GetRequiredService<IConfiguration>();
                var userList = config.GetSection("userList").Get<List<string>>();

                SeedData.Initialize(services, userList).Wait();
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred adding users.");
            }
        }

        host.Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

次のコードは、ユーザー追加の概要を示しています。


public static async Task Initialize(IServiceProvider serviceProvider,
                                    List<string> userList)
{
    var userManager = serviceProvider.GetService<UserManager<IdentityUser>>();

    foreach (var userName in userList)
    {
        var userPassword = GenerateSecurePassword();
        var userId = await EnsureUser(userManager, userName, userPassword);

        NotifyUser(userName, userPassword);
    }
}

private static async Task<string> EnsureUser(UserManager<IdentityUser> userManager,
                                             string userName, string userPassword)
{
    var user = await userManager.FindByNameAsync(userName);

    if (user == null)
    {
        user = new IdentityUser(userName)
        {
            EmailConfirmed = true
        };
        await userManager.CreateAsync(user, userPassword);
    }

    return user.Id;
}

実稼働シナリオでも、同様のアプローチに従うことができます。

静的 Identity アセットを発行しないようにする

静的 Identity アセットを Web ルートに発行しないようにするには、「ASP.NET Core の Identity の概要」を参照してください。

ASP.NET Core では、ASP.NET Core IdentityRazor クラス ライブラリ (RCL) として提供しています。 Identity を含むアプリケーションでは、Identity RCL に含まれるソース コードを選択的に追加するようにスキャフォールディングを適用できます。 コードを変更して動作を変更できるように、ソース コードを生成できます。 たとえば、登録で使用するコードを生成するようにスキャフォルダーに指示できます。 生成されたコードは、Identity RCL の同じコードよりも優先されます。 UI を完全に制御し、既定の RCL を使用しないようにするには、「完全な Identity UI ソースを作成する」セクションを参照してください。

認証を含まないアプリケーションでは、RCL Identity パッケージを追加するようにスキャフォールディングを適用できます。 生成される Identity コードの選択オプションがあります。

スキャフォールディングによって、必要なコードの大部分が生成されますが、プロセスを完了するにはプロジェクトを更新する必要があります。 このドキュメントでは、Identity スキャフォールディングの更新を完了するために必要な手順について説明します。

ファイルの差分が表示され、変更を取り消すことができるソース管理システムを使用することをお勧めします。 Identity スキャフォールディングを実行した後、変更内容を検査します。

サービスは、Identity で 2 要素認証アカウントの確認とパスワードの回復、およびその他のセキュリティ機能を使用する場合に必要です。 サービスまたはサービス スタブは、Identity のスキャフォールディング時に生成されません。 これらの機能を有効にするサービスは、手動で追加する必要があります。 たとえば、電子メール確認の要求に関する記事をご覧ください。

既存の個別のアカウントで、新しいデータ コンテキストを持つプロジェクトに Identity をスキャフォールディングする場合は、Startup.ConfigureServices を開き、以下から呼び出しを削除します。

  • AddDbContext
  • AddDefaultIdentity

たとえば、次のコードでは、AddDbContextAddDefaultIdentity がコメントアウトされています。

public void ConfigureServices(IServiceCollection services)
{
    //services.AddDbContext<ApplicationDbContext>(options =>
    //    options.UseSqlServer(
    //        Configuration.GetConnectionString("DefaultConnection")));
    //services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    //    .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddControllersWithViews();
    services.AddRazorPages();
}

上記のコードでは、Areas/Identity/IdentityHostingStartup.cs 内で重複しているコードがコメント アウトされています

通常は、個別のアカウントで作成されたアプリでは、新しいデータ コンテキストを作成 "しない" ようにする必要があります。

空のプロジェクトに Identity をスキャフォールディングする

Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

Startup クラスを次のようなコードで更新します。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            endpoints.MapRazorPages();
        });
    }
}

UseHsts は推奨されますが必須ではありません。 詳細については、HTTP トランスポート セキュリティのプロトコルに関するページを参照してください。

生成された Identity データベース コードには、Entity Framework (EF) Core 移行が必要です。 Identity スキーマを作成するための移行が作成されておらず、データベースに適用されていない場合は、移行を作成してデータベースを更新します。

Visual Studio Connected Services で EF Core 移行を追加し、データベースを更新します。

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[移行の追加] を選択します。

移行には、その移行を説明する名前である移行の名前 (CreateIdentitySchema など) を付けます。 データベース コンテキストが [DbContext クラス名] フィールドに読み込まれるのを待ちます。これは数秒かかる場合があります。 [完了] を選択して移行を作成します。

操作の完了後、[閉じる] ボタンを選択します。

省略記号 (...) をもう一度選択し、次に [データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

データベースの更新コマンドは、スキャフォールディングによって作成された移行コード ファイルに適用されていない Up メソッドの移行を行います。 この場合、コマンドは Migrations/{TIME STAMP}_{MIGRATION NAME}.cs ファイル内の Up メソッドを実行し、Identity テーブル、制約、インデックスを作成します。 {TIME STAMP} プレースホルダーはタイム スタンプであり、{MIGRATION NAME} プレースホルダーは移行名です。

Identity スキーマが既に作成されているが、データベースに適用されていない場合は、データベースを更新するコマンドのみを実行する必要があります:

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

次のコマンドを使用して、 Identity スキーマのアプリケーションを確認できます。 コマンドの出力には、データベースに適用される移行を示す "applied" 列が含まれています。

Visual Studio パッケージ マネージャー コンソールの場合は、Get-Migration を実行します:

Get-Migration

複数のデータベース コンテキストが存在する場合は、-Context パラメーターを使用してコンテキストを指定します。

Razor プロジェクトに既存の認可なしで Identity をスキャフォールディングする

Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

Identity は Areas/Identity/IdentityHostingStartup.cs で構成されます。 詳細については、IHostingStartupを参照してください。

移行、UseAuthentication、レイアウト

生成された Identity データベース コードには、Entity Framework (EF) Core 移行が必要です。 Identity スキーマを作成するための移行が作成されておらず、データベースに適用されていない場合は、移行を作成してデータベースを更新します。

Visual Studio Connected Services で EF Core 移行を追加し、データベースを更新します。

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[移行の追加] を選択します。

移行には、その移行を説明する名前である移行の名前 (CreateIdentitySchema など) を付けます。 データベース コンテキストが [DbContext クラス名] フィールドに読み込まれるのを待ちます。これは数秒かかる場合があります。 [完了] を選択して移行を作成します。

操作の完了後、[閉じる] ボタンを選択します。

省略記号 (...) をもう一度選択し、次に [データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

データベースの更新コマンドは、スキャフォールディングによって作成された移行コード ファイルに適用されていない Up メソッドの移行を行います。 この場合、コマンドは Migrations/{TIME STAMP}_{MIGRATION NAME}.cs ファイル内の Up メソッドを実行し、Identity テーブル、制約、インデックスを作成します。 {TIME STAMP} プレースホルダーはタイム スタンプであり、{MIGRATION NAME} プレースホルダーは移行名です。

Identity スキーマが既に作成されているが、データベースに適用されていない場合は、データベースを更新するコマンドのみを実行する必要があります:

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

次のコマンドを使用して、 Identity スキーマのアプリケーションを確認できます。 コマンドの出力には、データベースに適用される移行を示す "applied" 列が含まれています。

Visual Studio パッケージ マネージャー コンソールの場合は、Get-Migration を実行します:

Get-Migration

複数のデータベース コンテキストが存在する場合は、-Context パラメーターを使用してコンテキストを指定します。

認証を有効にする

Startup クラスを次のようなコードで更新します。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

UseHsts は推奨されますが必須ではありません。 詳細については、HTTP トランスポート セキュリティのプロトコルに関するページを参照してください。

レイアウトの変更

省略可能: ログイン部分 (_LoginPartial) をレイアウト ファイルに追加します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRP</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">WebRP</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <partial name="_LoginPartial" />
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2019 - WebRP - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @RenderSection("Scripts", required: false)
</body>
</html>

Razor プロジェクトに認可ありで Identity をスキャフォールディングする

Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

一部の Identity オプションは、Areas/Identity/IdentityHostingStartup.cs 内で構成されます。 詳細については、IHostingStartupを参照してください。

MVC プロジェクトに既存の認可なしで Identity をスキャフォールディングする

Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

省略可能: ログイン部分 (_LoginPartial) を Views/Shared/_Layout.cshtml ファイルに追加します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRP</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">WebRP</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <partial name="_LoginPartial" />
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2019 - WebRP - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @RenderSection("Scripts", required: false)
</body>
</html>

Pages/Shared/_LoginPartial.cshtml ファイルを Views/Shared/_LoginPartial.cshtml に移動します。

Identity は Areas/Identity/IdentityHostingStartup.cs で構成されます。 詳細については、IHostingStartupを参照してください。

生成された Identity データベース コードには、Entity Framework (EF) Core 移行が必要です。 Identity スキーマを作成するための移行が作成されておらず、データベースに適用されていない場合は、移行を作成してデータベースを更新します。

Visual Studio Connected Services で EF Core 移行を追加し、データベースを更新します。

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[移行の追加] を選択します。

移行には、その移行を説明する名前である移行の名前 (CreateIdentitySchema など) を付けます。 データベース コンテキストが [DbContext クラス名] フィールドに読み込まれるのを待ちます。これは数秒かかる場合があります。 [完了] を選択して移行を作成します。

操作の完了後、[閉じる] ボタンを選択します。

省略記号 (...) をもう一度選択し、次に [データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

データベースの更新コマンドは、スキャフォールディングによって作成された移行コード ファイルに適用されていない Up メソッドの移行を行います。 この場合、コマンドは Migrations/{TIME STAMP}_{MIGRATION NAME}.cs ファイル内の Up メソッドを実行し、Identity テーブル、制約、インデックスを作成します。 {TIME STAMP} プレースホルダーはタイム スタンプであり、{MIGRATION NAME} プレースホルダーは移行名です。

Identity スキーマが既に作成されているが、データベースに適用されていない場合は、データベースを更新するコマンドのみを実行する必要があります:

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

次のコマンドを使用して、 Identity スキーマのアプリケーションを確認できます。 コマンドの出力には、データベースに適用される移行を示す "applied" 列が含まれています。

Visual Studio パッケージ マネージャー コンソールの場合は、Get-Migration を実行します:

Get-Migration

複数のデータベース コンテキストが存在する場合は、-Context パラメーターを使用してコンテキストを指定します。

Startup クラスを次のようなコードで更新します。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            endpoints.MapRazorPages();
        });
    }
}

UseHsts は推奨されますが必須ではありません。 詳細については、HTTP トランスポート セキュリティのプロトコルに関するページを参照してください。

MVC プロジェクトに認可ありで Identity をスキャフォールディングする

Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

既存の承認なしでサーバーサイド Blazor アプリに Identity をスキャフォールディングする

Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

Identity は Areas/Identity/IdentityHostingStartup.cs で構成されます。 詳細については、IHostingStartupを参照してください。

移行

生成された Identity データベース コードには、Entity Framework (EF) Core 移行が必要です。 Identity スキーマを作成するための移行が作成されておらず、データベースに適用されていない場合は、移行を作成してデータベースを更新します。

Visual Studio Connected Services で EF Core 移行を追加し、データベースを更新します。

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[移行の追加] を選択します。

移行には、その移行を説明する名前である移行の名前 (CreateIdentitySchema など) を付けます。 データベース コンテキストが [DbContext クラス名] フィールドに読み込まれるのを待ちます。これは数秒かかる場合があります。 [完了] を選択して移行を作成します。

操作の完了後、[閉じる] ボタンを選択します。

省略記号 (...) をもう一度選択し、次に [データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

データベースの更新コマンドは、スキャフォールディングによって作成された移行コード ファイルに適用されていない Up メソッドの移行を行います。 この場合、コマンドは Migrations/{TIME STAMP}_{MIGRATION NAME}.cs ファイル内の Up メソッドを実行し、Identity テーブル、制約、インデックスを作成します。 {TIME STAMP} プレースホルダーはタイム スタンプであり、{MIGRATION NAME} プレースホルダーは移行名です。

Identity スキーマが既に作成されているが、データベースに適用されていない場合は、データベースを更新するコマンドのみを実行する必要があります:

ソリューション エクスプローラーで、[Connected Services] をダブルクリックします。 Service Dependencies[SQL Server Express LocalDB] 領域で、省略記号 (...) を選択し、[データベースの更新] コマンドを選択します。

[データベースを最新の移行で更新] ダイアログが開きます。 [DbContext クラス名] フィールドが更新され、以前の移行が読み込まれるまで待ちます。これは数秒かかる場合があります。 [完了] ボタンを選択します。

操作の完了後、[閉じる] ボタンを選択します。

次のコマンドを使用して、 Identity スキーマのアプリケーションを確認できます。 コマンドの出力には、データベースに適用される移行を示す "applied" 列が含まれています。

Visual Studio パッケージ マネージャー コンソールの場合は、Get-Migration を実行します:

Get-Migration

複数のデータベース コンテキストが存在する場合は、-Context パラメーターを使用してコンテキストを指定します。

認証エンドポイントをスタイル設定する

サーバーサイド Blazor アプリでは RazorPagesIdentity ページが使用されているため、訪問者が Identity ページとコンポーネント間を移動すると、UI のスタイルが変わります。 調和していないスタイルに対処するには、次の 2 つの選択肢があります。

カスタム Identity コンポーネント

ページの代わりに Identity のコンポーネントを使用する方法で、Identity コンポーネントを構築します。 SignInManagerUserManager は Razor コンポーネントでサポートされていないため、Blazor アプリで web API エンドポイントを使用してユーザー アカウントの操作を処理します。

Blazor アプリのスタイルでカスタム レイアウトを使用する

Identity ページのレイアウトとスタイルを変更して、既定の Blazor テーマと似たようなスタイルを使用するページを生成できます。 この方法については、ドキュメントでは説明しません。

承認を使用してサーバーサイド Blazor アプリに Identity をスキャフォールディングする

Identity スキャフォールディングを実行します。

  • [ソリューション エクスプローラー] で、プロジェクトを右クリックし、>[追加]>[新しいスキャフォールディング アイテム] の順に選択します。
  • [新規スキャフォールディング アイテムの追加] の左ペインから [Identity] を選択します。 中央のウィンドウで [Identity] を選択します。 追加 ボタンを選択します。
  • [Identity の追加] ダイアログで、必要なオプションを選択します。
    • Identity (_Layout.cshtml) 用にカスタマイズされた既存のレイアウト ページがある場合は、既存のレイアウト ページを選択して、スキャフォールディングによって正しくないマークアップでレイアウトが上書きされないようにします。 たとえば、次のいずれかを選択します:
      • 既存の Razor Pages インフラストラクチャが含まれる、Razor Pages プロジェクトまたは Blazor Server プロジェクトの Pages/Shared/_Layout.cshtml
      • 既存の MVC インフラストラクチャが含まれる、MVC プロジェクトまたは Blazor Server プロジェクトの Views/Shared/_Layout.cshtml
    • データ コンテキスト (DbContext クラス) の場合:
      • データ コンテキスト クラスを選択します。 データ コンテキストを追加するには、1 つ以上のファイルを選択する必要があります。
      • データ コンテキストを作成し、Identity の新しいユーザー クラスを作成するには、+ ボタンを選択します。 既定値をそのまま使用するか、クラスを指定します (たとえば、 "Contoso" という名前の会社の場合は Contoso.Data.ApplicationDbContext)。 新しいユーザー クラスを作成するには、[+ユーザー クラス] のボタンを選択し、クラスを指定します (たとえば、ContosoUser"Contoso" という名前の会社の場合)。
    • [追加] ボタンを選択してスキャフォールディングを実行します。

一部の Identity オプションは、Areas/Identity/IdentityHostingStartup.cs 内で構成されます。 詳細については、IHostingStartupを参照してください。

クライアントサイド Blazor アプリ

クライアント側の Blazor アプリでは独自の Identity UI アプローチを使用し、ASP.NET Core Identity スキャフォールディングを使用することはできません。 ホストされた Blazor ソリューションのサーバー側の ASP.NET Core アプリは、この記事の Razor Pages/MVC ガイダンスに従うことができ、Identity をサポートする他の種類の ASP.NET Core アプリと同様に構成します。

Blazor フレームワークには、Razor コンポーネント バージョンの Identity UI ページは含まれていません。 Identity UI Razor コンポーネントは、カスタムで作成するか、サポートされていないサードパーティのソースから取得できます。

詳細については、Blazor セキュリティと Identity に関する記事をご覧ください。

完全な Identity UI ソースを作成する

Identity UI の完全な制御を維持するには、Identity スキャフォールディングを実行し、[すべてのファイルをオーバーライド] を選択します。

次の強調表示されたコードは、ASP.NET Core 2.1 Web アプリで既定の Identity UI を Identity に置き換える変更を示しています。 Identity UI を完全に制御するには、これを行うことをお勧めします。

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<IdentityUser, IdentityRole>()
        // services.AddDefaultIdentity<IdentityUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddMvc()
        .AddRazorPagesOptions(options =>
        {
            options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
            options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
        });

    services.ConfigureApplicationCookie(options =>
    {
        options.LoginPath = $"/Identity/Account/Login";
        options.LogoutPath = $"/Identity/Account/Logout";
        options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
    });

    // using Microsoft.AspNetCore.Identity.UI.Services;
    services.AddSingleton<IEmailSender, EmailSender>();
}

次のコードで、既定の Identity が置き換えられています。

services.AddIdentity<IdentityUser, IdentityRole>()
    // services.AddDefaultIdentity<IdentityUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

次のコードでは、LoginPathLogoutPathAccessDeniedPath を設定します。

services.ConfigureApplicationCookie(options =>
{
    options.LoginPath = $"/Identity/Account/Login";
    options.LogoutPath = $"/Identity/Account/Logout";
    options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});

たとえば、IEmailSender の実装を登録します。

// using Microsoft.AspNetCore.Identity.UI.Services;
services.AddSingleton<IEmailSender, EmailSender>();
public class EmailSender : IEmailSender
{
    public Task SendEmailAsync(string email, string subject, string message)
    {
        return Task.CompletedTask;
    }
}

パスワードの構成

PasswordOptionsStartup.ConfigureServices で構成されている場合、[StringLength] 属性の構成が、スキャフォールディングされる Identity ページの Password プロパティに必要になることがあります。 InputModel Password プロパティは、次のファイルにあります。

  • Areas/Identity/Pages/Account/Register.cshtml.cs
  • Areas/Identity/Pages/Account/ResetPassword.cshtml.cs

ページを無効にする

このセクションでは、登録ページを無効にする方法を示しますが、この方法を使用して任意のページを無効にできます。

ユーザー登録を無効にするには、次のようにします。

  • Identity をスキャフォールディングします。 Account.Register、Account.Login、Account.RegisterConfirmation を含めます。 次に例を示します。

    dotnet aspnet-codegenerator identity -dc RPauth.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.RegisterConfirmation"
    
  • Areas/Identity/Pages/Account/Register.cshtml.cs を更新して、ユーザーがこのエンドポイントから登録できないようにします。

    public class RegisterModel : PageModel
    {
        public IActionResult OnGet()
        {
            return RedirectToPage("Login");
        }
    
        public IActionResult OnPost()
        {
            return RedirectToPage("Login");
        }
    }
    
  • 前の変更と一致するように Areas/Identity/Pages/Account/Register.cshtml を更新します。

    @page
    @model RegisterModel
    @{
        ViewData["Title"] = "Go to Login";
    }
    
    <h1>@ViewData["Title"]</h1>
    
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
    
  • コメント アウトするか Areas/Identity/Pages/Account/Login.cshtml から登録リンクを削除します

    @*
    <p>
        <a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
    </p>
    *@
    
  • Areas/Identity/Pages/Account/RegisterConfirmation ページを更新します。

    • cshtml ファイルからコードとリンクを削除します。
    • PageModel から確認コードを削除します。
    [AllowAnonymous]
      public class RegisterConfirmationModel : PageModel
      {
          public IActionResult OnGet()
          {  
              return Page();
          }
      }
    

別のアプリを使用してユーザーを追加する

Web アプリの外部にユーザーを追加するメカニズムを提供します。 ユーザーを追加するオプションには次のものがあります。

  • 専用管理者の Web アプリ。
  • コンソール アプリ。

次のコードは、ユーザーを追加する 1 つの方法の概要を示しています。

  • ユーザーの一覧がメモリに読み込まれる。
  • ユーザーごとに強力な一意のパスワードが生成される。
  • ユーザーが Identity データベースに追加される。
  • ユーザーに通知され、パスワードを変更するように指示される。
public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();

        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                var context = services.GetRequiredService<AppDbCntx>();
                context.Database.Migrate();

                var config = host.Services.GetRequiredService<IConfiguration>();
                var userList = config.GetSection("userList").Get<List<string>>();

                SeedData.Initialize(services, userList).Wait();
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred adding users.");
            }
        }

        host.Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

次のコードは、ユーザー追加の概要を示しています。


public static async Task Initialize(IServiceProvider serviceProvider,
                                    List<string> userList)
{
    var userManager = serviceProvider.GetService<UserManager<IdentityUser>>();

    foreach (var userName in userList)
    {
        var userPassword = GenerateSecurePassword();
        var userId = await EnsureUser(userManager, userName, userPassword);

        NotifyUser(userName, userPassword);
    }
}

private static async Task<string> EnsureUser(UserManager<IdentityUser> userManager,
                                             string userName, string userPassword)
{
    var user = await userManager.FindByNameAsync(userName);

    if (user == null)
    {
        user = new IdentityUser(userName)
        {
            EmailConfirmed = true
        };
        await userManager.CreateAsync(user, userPassword);
    }

    return user.Id;
}

実稼働シナリオでも、同様のアプローチに従うことができます。

静的 Identity アセットを発行しないようにする

静的 Identity アセットを Web ルートに発行しないようにするには、「ASP.NET Core の Identity の概要」を参照してください。

その他のリソース

ASP.NET Core 2.1 以降への認証コードの変更