次の方法で共有


ASP.NET Core cookie を使用せずに Identity 認証を使用する

作成者: Rick Anderson

ASP.NET Core Identity は、ログインを作成および管理するための、完全な機能を備えた認証プロバイダーです。 ただし、ASP.NET Core cookie を使用しない Identity ベースの認証プロバイダーを使用することができます。 詳細については、「ASP.NET Core の Identity の概要」を参照してください。

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

サンプル アプリでのデモンストレーションのため、架空のユーザー Maria Rodriguez のユーザー アカウントがアプリにハードコーディングされています。 メール アドレス maria.rodriguez@contoso.com と任意のパスワードを使用して、ユーザーにサインインします。 ユーザーは、AuthenticateUser ファイルの Pages/Account/Login.cshtml.cs メソッドで認証されます。 実際の例では、ユーザーはデータストアに対して認証されます。

Important

ASP.NET Core 10 以降では、既知の API エンドポイントは、 cookie 認証を使用するときにログイン ページにリダイレクトされなくなりました。 代わりに、401/403 状態コードが返されます。 詳細については、 ASP.NET Core での API エンドポイント認証の動作に関するページを参照してください。

using Microsoft.AspNetCore.Authentication.Cookies;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie();

builder.Services.AddHttpContextAccessor();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

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

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

AuthenticationScheme に渡される AddAuthentication によって、アプリの既定の認証方式が設定されます。 AuthenticationScheme は、cookie 認証の複数のインスタンスがあり、アプリで特定の方式の承認を行う必要がある場合に便利です。 AuthenticationSchemeCookieAuthenticationDefaults.AuthenticationScheme に設定すると、スキームに"Cookies"の値が提供されます。 スキームを区別する任意の文字列値を使用できます。

CookieAuthenticationDefaults.AuthenticationScheme (既定値: "Cookies") がスキームとして使用されていない場合は、認証プロバイダーを構成するときに使用するスキームを指定します。 それ以外の場合は、既定の方式が使用されます。 たとえば、スキームとして "ContosoCookie" を使用する場合は、認証プロバイダーの構成時に使用するスキームを指定します。

認証 cookie の IsEssential プロパティは、既定で true に設定されます。 サイト ビジターがデータ収集に同意していない場合、認証 Cookie が許可されます。 詳細については、「General Data Protection Regulation (GDPR) support in ASP.NET Core」(ASP.NET Core での一般データ保護規則 (GDPR) のサポート) をご覧ください。

認証プロバイダーのオプションを構成するには、CookieAuthenticationOptions クラスを使用します。

メソッド CookieAuthenticationOptionsAddCookie を構成します。

using Microsoft.AspNetCore.Authentication.Cookies;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
        options.SlidingExpiration = true;
        options.AccessDeniedPath = "/Forbidden/";
    });

builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

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

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

Cookie ポリシー ミドルウェア (GitHub ソース)UseCookiePolicy を使うと、cookie ポリシー機能を有効にすることができます。 ミドルウェアは追加された順序で処理され、Cookie ポリシー ミドルウェアはcookie 認証ミドルウェアの前に追加する必要があります。

CookiePolicyOptions 処理のグローバル特性を制御し、Cookie が追加または削除されたときに Cookie 処理ハンドラーにフックするには、cookie ポリシー ミドルウェアに提供される cookie を使用します。

MinimumSameSitePolicy の既定値は SameSiteMode.Lax で、OAuth2 認証を許可します。 SameSiteMode.Strict と同じサイト ポリシーを厳密に適用するには、MinimumSameSitePolicy を設定します。 これを設定すると、OAuth2 や他のクロスオリジン認証方式は機能しなくなりますが、クロスオリジン要求処理に依存しない他の種類のアプリの cookie セキュリティのレベルが上がります。

次の例では、cookie ポリシー ミドルウェアを使用してCookie認証を構成する方法を示します。

var cookiePolicyOptions = new CookiePolicyOptions
{
    MinimumSameSitePolicy = SameSiteMode.Strict,
};

app.UseCookiePolicy(cookiePolicyOptions);

Cookie に対する MinimumSameSitePolicy ポリシー ミドルウェアの設定は、次の表に従って、Cookie.SameSite の設定における CookieAuthenticationOptions の設定に影響する場合があります。

MinimumSameSitePolicy Cookie.SameSite 結果の Cookie.SameSite の設定
SameSiteMode.None SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict

ユーザー情報を保持する cookie を作成するには、ClaimsPrincipal を構築します。 ユーザー情報は、シリアル化されて cookie に格納されます。

任意の必要な ClaimsIdentity を使用して Claim を作成し、SignInAsync を呼び出してユーザーをサインインさせます。 サンプル アプリの Login.cshtml.cs には、次のコードが含まれています。

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    ReturnUrl = returnUrl;

    if (ModelState.IsValid)
    {
        // Use Input.Email and Input.Password to authenticate the user
        // with your custom authentication logic.
        //
        // For demonstration purposes, the sample validates the user
        // on the email address maria.rodriguez@contoso.com with 
        // any password that passes model validation.

        var user = await AuthenticateUser(Input.Email, Input.Password);

        if (user == null)
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, user.Email),
            new Claim("FullName", user.FullName),
            new Claim(ClaimTypes.Role, "Administrator"),
        };

        var claimsIdentity = new ClaimsIdentity(
            claims, CookieAuthenticationDefaults.AuthenticationScheme);

        var authProperties = new AuthenticationProperties
        {
            //AllowRefresh = <bool>,
            // Refreshing the authentication session should be allowed.

            //ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
            // The time at which the authentication ticket expires. A 
            // value set here overrides the ExpireTimeSpan option of 
            // CookieAuthenticationOptions set with AddCookie.

            //IsPersistent = true,
            // Whether the authentication session is persisted across 
            // multiple requests. When used with cookies, controls
            // whether the cookie's lifetime is absolute (matching the
            // lifetime of the authentication ticket) or session-based.

            //IssuedUtc = <DateTimeOffset>,
            // The time at which the authentication ticket was issued.

            //RedirectUri = <string>
            // The full path or absolute URI to be used as an http 
            // redirect response value.
        };

        await HttpContext.SignInAsync(
            CookieAuthenticationDefaults.AuthenticationScheme, 
            new ClaimsPrincipal(claimsIdentity), 
            authProperties);

        _logger.LogInformation("User {Email} logged in at {Time}.", 
            user.Email, DateTime.UtcNow);

        return LocalRedirect(Url.GetLocalUrl(returnUrl));
    }

    // Something failed. Redisplay the form.
    return Page();
}

コードのコメントを英語以外の言語に翻訳し表示したい場合、こちらの GitHub ディスカッション イシューにてお知らせください。

SignInAsync によって暗号化された cookie が作成されて、現在の応答に追加されます。 AuthenticationScheme が指定されていない場合は、既定の方式が使用されます。

RedirectUri は、既定では少数の特定のパス (ログイン パスやログアウト パスなど) でのみ使用されます。 詳細については、「CookieAuthenticationHandler の ソース」をご覧ください。

暗号化には、ASP.NET Core のデータ保護システムが使用されます。 複数のコンピューターでホストされているアプリの場合、アプリ間で負荷を分散する場合、または Web ファームを使用する場合は、同じキー リングとアプリ識別子を使用するように、データ保護を構成します。

サインアウト

現在のユーザーをサインアウトさせてその cookie を削除するには、SignOutAsync を呼び出します。

public async Task OnGetAsync(string returnUrl = null)
{
    if (!string.IsNullOrEmpty(ErrorMessage))
    {
        ModelState.AddModelError(string.Empty, ErrorMessage);
    }

    // Clear the existing external cookie
    await HttpContext.SignOutAsync(
        CookieAuthenticationDefaults.AuthenticationScheme);

    ReturnUrl = returnUrl;
}

CookieAuthenticationDefaults.AuthenticationScheme (既定値: "Cookies") がスキームとして使用されていない場合は、認証プロバイダーを構成するときに使用するスキームを指定します。 それ以外の場合は、既定の方式が使用されます。 たとえば、スキームとして "ContosoCookie" を使用する場合は、認証プロバイダーの構成時に使用するスキームを指定します。

ブラウザーが閉じられると、セッション ベースの cookie (非永続的な cookie) は自動的に削除されますが、個々のタブが閉じられたときは、cookie はクリアされません。 サーバーには、タブまたはブラウザーが閉じられたイベントは通知されません。

バックエンドの変更に対応する

cookieが作成されると、cookieは ID の単一のソースになります。 バックエンド システムでユーザー アカウントが無効にされた場合:

  • アプリの cookie 認証システムによる要求の処理は、認証 cookie に基づいて続けられます。
  • 認証 cookie が有効である限り、ユーザーはアプリにサインインしたままになります。

ValidatePrincipal イベントを使用して、cookie ID の検証をインターセプトおよびオーバーライドできます。 すべての要求で cookie を検証すると、取り消されたユーザーがアプリにアクセスするリスクが軽減されます。

cookie を検証する方法の 1 つは、ユーザー データベースの変更を追跡することです。 ユーザーの cookie が発行された後でデータベースが変更されていない場合は、その cookie がまだ有効であれば、再認証を行う必要はありません。 サンプル アプリでは、データベースは IUserRepository に実装され、そこに LastChanged の値が格納されます。 データベースでユーザーが更新されると、LastChanged の値に現在時刻が設定されます。

cookie の値に基づいてデータベースが変更されたときに LastChanged を無効にするには、データベースの現在の cookie の値を含む LastChanged クレームを使用して LastChanged を作成します。

var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, user.Email),
    new Claim("LastChanged", {Database Value})
};

var claimsIdentity = new ClaimsIdentity(
    claims,
    CookieAuthenticationDefaults.AuthenticationScheme);

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme, 
    new ClaimsPrincipal(claimsIdentity));

ValidatePrincipal イベントのオーバーライドを実装するには、CookieAuthenticationEvents から派生するクラスに次のシグネチャを持つメソッドを記述します。

ValidatePrincipal(CookieValidatePrincipalContext)

CookieAuthenticationEvents の実装例を次に示します。

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;

public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
    private readonly IUserRepository _userRepository;

    public CustomCookieAuthenticationEvents(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
    {
        var userPrincipal = context.Principal;

        // Look for the LastChanged claim.
        var lastChanged = (from c in userPrincipal.Claims
                           where c.Type == "LastChanged"
                           select c.Value).FirstOrDefault();

        if (string.IsNullOrEmpty(lastChanged) ||
            !_userRepository.ValidateLastChanged(lastChanged))
        {
            context.RejectPrincipal();

            await context.HttpContext.SignOutAsync(
                CookieAuthenticationDefaults.AuthenticationScheme);
        }
    }
}

cookie サービスの登録中にイベント インスタンスを登録します。 クラスに対してCustomCookieAuthenticationEventsを提供します。

using Microsoft.AspNetCore.Authentication.Cookies;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.EventsType = typeof(CustomCookieAuthenticationEvents);
    });

builder.Services.AddScoped<CustomCookieAuthenticationEvents>();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

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

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

ユーザーの名前が更新される場合について考えます。これは、セキュリティにまったく影響を与えない決定です。 ユーザー プリンシパルを非破壊的に更新したい場合は、context.ReplacePrincipal を呼び出し、context.ShouldRenew プロパティを true に設定します。

Warning

ここで説明するアプローチは、すべての要求でトリガーされます。 すべての要求ですべてのユーザーについて認証 cookie を検証すると、アプリのパフォーマンスが大幅に低下する可能性があります。

永続的な Cookie

cookie をブラウザー セッション間で永続化することができます。 この永続化は、サインイン時の "アカウントを記憶する" チェック ボックスや同様のメカニズムによって、ユーザーの明示的な同意がある場合にのみ有効にする必要があります。

次のコード スニペットは、ブラウザーの終了後も存続するアイデンティティと該当するcookieを作成します。 以前に構成されたスライド式有効期限の設定が尊重されます。 ブラウザーが閉じられている間に cookie の有効期限が切れると、ブラウザーの再起動時に cookie はクリアされます。

IsPersistenttrueAuthenticationProperties に設定します。

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true
    });

ExpiresUtc を使用して、絶対的な有効期限を設定できます。 永続的な cookie を作成するには、IsPersistent も設定する必要があります。 そうしないと、cookie はセッション ベースの有効期間で作成され、保持されている認証チケットの前または後に期限切れになる可能性があります。 ExpiresUtc が設定されていると、ExpireTimeSpanCookieAuthenticationOptions オプションの値が設定されている場合はオーバーライドされます。

次のコード スニペットは、20 分間続く ID と対応する cookie を作成します。 これにより、以前に構成されたスライド式有効期限の設定はすべて無視されます。

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true,
        ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
    });

ASP.NET Core Identity は、ログインを作成および管理するための、完全な機能を備えた認証プロバイダーです。 ただし、ASP.NET Core cookie を使用しない Identity ベースの認証プロバイダーを使用することができます。 詳細については、「ASP.NET Core の Identity の概要」を参照してください。

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

サンプル アプリでのデモンストレーションのため、架空のユーザー Maria Rodriguez のユーザー アカウントがアプリにハードコーディングされています。 メール アドレス maria.rodriguez@contoso.com と任意のパスワードを使用して、ユーザーにサインインします。 ユーザーは、AuthenticateUser ファイルの Pages/Account/Login.cshtml.cs メソッドで認証されます。 現実の例では、ユーザーはデータベースに対して認証されます。

Configuration

Startup.ConfigureServices メソッドでは、AddAuthentication および AddCookie メソッドを使用して認証ミドルウェア サービスが作成されます。

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie();

AuthenticationScheme に渡される AddAuthentication によって、アプリの既定の認証方式が設定されます。 AuthenticationScheme は、cookie 認証の複数のインスタンスがあり、特定の方式で承認を行う場合に便利です。 AuthenticationSchemeCookieAuthenticationDefaults.AuthenticationScheme に設定すると、スキームの値 "Cookie" が提供されます。 方式を区別する任意の文字列値を指定できます。

アプリの認証方式は、アプリの cookie 認証方式とは異なります。 cookie 認証スキームが AddCookie に提供されていない場合は、CookieAuthenticationDefaults.AuthenticationScheme (「Cookie」) が使用されます。

認証 cookie の IsEssential プロパティは、既定で true に設定されます。 サイト ビジターがデータ収集に同意していない場合、認証 Cookie が許可されます。 詳細については、「General Data Protection Regulation (GDPR) support in ASP.NET Core」(ASP.NET Core での一般データ保護規則 (GDPR) のサポート) をご覧ください。

Startup.Configure で、UseAuthenticationUseAuthorization を呼び出して HttpContext.User プロパティを設定し、要求に対して認可ミドルウェアを実行します。 UseAuthentication を呼び出す前に、UseAuthorization および UseEndpoints メソッドを呼び出します。

認証プロバイダーのオプションを構成するには、CookieAuthenticationOptions クラスを使用します。

CookieAuthenticationOptions メソッドの認証用のサービス構成で Startup.ConfigureServices を設定します。

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        ...
    });

Cookie ポリシー ミドルウェアを使用すると、cookie ポリシー機能が有効になります。 ミドルウェアをアプリ処理パイプラインに追加するのは順序が重要です。パイプラインに登録されているダウンストリーム コンポーネントにのみ影響します。 Cookie ポリシー ミドルウェアは、認証ミドルウェア cookie 前に追加する必要があります。

CookiePolicyOptions 処理のグローバル特性を制御し、Cookie が追加または削除されたときに Cookie 処理ハンドラーにフックするには、cookie ポリシー ミドルウェアに提供される cookie を使用します。

MinimumSameSitePolicy の既定値は SameSiteMode.Lax で、OAuth2 認証を許可します。 SameSiteMode.Strict と同じサイト ポリシーを厳密に適用するには、MinimumSameSitePolicy を設定します。 これを設定すると、OAuth2 や他のクロスオリジン認証方式は機能しなくなりますが、クロスオリジン要求処理に依存しない他の種類のアプリの cookie セキュリティのレベルが上がります。

次の例では、cookie ポリシー ミドルウェアを使用してCookie認証を構成する方法を示します。

var cookiePolicyOptions = new CookiePolicyOptions
{
    MinimumSameSitePolicy = SameSiteMode.Strict,
};

app.UseCookiePolicy(cookiePolicyOptions);

Cookie に対する MinimumSameSitePolicy ポリシー ミドルウェアの設定は、次の表に従って、Cookie.SameSite の設定における CookieAuthenticationOptions の設定に影響する場合があります。

MinimumSameSitePolicy Cookie.SameSite 結果の Cookie.SameSite の設定
SameSiteMode.None SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict

ユーザー情報を保持する cookie を作成するには、ClaimsPrincipal を構築します。 ユーザー情報は、シリアル化されて cookie に格納されます。

任意の必要な ClaimsIdentity を使用して Claim を作成し、SignInAsync を呼び出してユーザーをサインインさせます。

var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, user.Email),
    new Claim("FullName", user.FullName),
    new Claim(ClaimTypes.Role, "Administrator"),
};

var claimsIdentity = new ClaimsIdentity(
    claims, CookieAuthenticationDefaults.AuthenticationScheme);

var authProperties = new AuthenticationProperties
{
    //AllowRefresh = <bool>,
    // Refreshing the authentication session should be allowed.

    //ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
    // The time at which the authentication ticket expires. A 
    // value set here overrides the ExpireTimeSpan option of 
    // CookieAuthenticationOptions set with AddCookie.

    //IsPersistent = true,
    // Whether the authentication session is persisted across 
    // multiple requests. When used with cookies, controls
    // whether the cookie's lifetime is absolute (matching the
    // lifetime of the authentication ticket) or session-based.

    //IssuedUtc = <DateTimeOffset>,
    // The time at which the authentication ticket was issued.

    //RedirectUri = <string>
    // The full path or absolute URI to be used as an http 
    // redirect response value.
};

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme, 
    new ClaimsPrincipal(claimsIdentity), 
    authProperties);

コードのコメントを英語以外の言語に翻訳し表示したい場合、こちらの GitHub ディスカッション イシューにてお知らせください。

SignInAsync によって暗号化された cookie が作成されて、現在の応答に追加されます。 AuthenticationScheme が指定されていない場合は、既定の方式が使用されます。

RedirectUri は、既定では少数の特定のパス (ログイン パスやログアウト パスなど) でのみ使用されます。 詳細については、「CookieAuthenticationHandler の ソース」をご覧ください。

暗号化には、ASP.NET Core のデータ保護システムが使用されます。 複数のコンピューターでホストされているアプリの場合、アプリ間で負荷を分散する場合、または Web ファームを使用する場合は、同じキー リングとアプリ識別子を使用するように、データ保護を構成します。

サインアウト

現在のユーザーをサインアウトさせてその cookie を削除するには、SignOutAsync を呼び出します。

await HttpContext.SignOutAsync(
    CookieAuthenticationDefaults.AuthenticationScheme);

CookieAuthenticationDefaults.AuthenticationScheme (既定値: "Cookies") がスキームとして使用されていない場合は、認証プロバイダーを構成するときに使用するスキームを指定します。 それ以外の場合は、既定の方式が使用されます。 たとえば、スキームとして "ContosoCookie" を使用する場合は、認証プロバイダーの構成時に使用するスキームを指定します。

ブラウザーが閉じられると、セッション ベースの cookie (非永続的な cookie) は自動的に削除されますが、個々のタブが閉じられたときは、cookie はクリアされません。 サーバーには、タブまたはブラウザーが閉じられたイベントは通知されません。

バックエンドの変更に対応する

cookieが作成されると、cookieは ID の単一のソースになります。 バックエンド システムでユーザー アカウントが無効にされた場合:

  • アプリの cookie 認証システムによる要求の処理は、認証 cookie に基づいて続けられます。
  • 認証 cookie が有効である限り、ユーザーはアプリにサインインしたままになります。

ValidatePrincipal イベントを使用して、cookie ID の検証をインターセプトおよびオーバーライドできます。 すべての要求で cookie を検証すると、取り消されたユーザーがアプリにアクセスするリスクが軽減されます。

cookie を検証する方法の 1 つは、ユーザー データベースの変更を追跡することです。 ユーザーの cookie が発行された後でデータベースが変更されていない場合は、その cookie がまだ有効であれば、再認証を行う必要はありません。 サンプル アプリでは、データベースは IUserRepository に実装され、そこに LastChanged の値が格納されます。 データベースでユーザーが更新されると、LastChanged の値に現在時刻が設定されます。

cookie の値に基づいてデータベースが変更されたときに LastChanged を無効にするには、データベースの現在の cookie の値を含む LastChanged クレームを使用して LastChanged を作成します。

var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, user.Email),
    new Claim("LastChanged", {Database Value})
};

var claimsIdentity = new ClaimsIdentity(
    claims, 
    CookieAuthenticationDefaults.AuthenticationScheme);

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme, 
    new ClaimsPrincipal(claimsIdentity));

ValidatePrincipal イベントのオーバーライドを実装するには、CookieAuthenticationEvents から派生するクラスに次のシグネチャを持つメソッドを記述します。

ValidatePrincipal(CookieValidatePrincipalContext)

CookieAuthenticationEvents の実装例を次に示します。

using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;

public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
    private readonly IUserRepository _userRepository;

    public CustomCookieAuthenticationEvents(IUserRepository userRepository)
    {
        // Get the database from registered DI services.
        _userRepository = userRepository;
    }

    public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
    {
        var userPrincipal = context.Principal;

        // Look for the LastChanged claim.
        var lastChanged = (from c in userPrincipal.Claims
                           where c.Type == "LastChanged"
                           select c.Value).FirstOrDefault();

        if (string.IsNullOrEmpty(lastChanged) ||
            !_userRepository.ValidateLastChanged(lastChanged))
        {
            context.RejectPrincipal();

            await context.HttpContext.SignOutAsync(
                CookieAuthenticationDefaults.AuthenticationScheme);
        }
    }
}

cookie メソッドで Startup.ConfigureServices サービスを登録する間にイベント インスタンスを登録します。 クラスに対してCustomCookieAuthenticationEventsを提供します。

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.EventsType = typeof(CustomCookieAuthenticationEvents);
    });

services.AddScoped<CustomCookieAuthenticationEvents>();

ユーザーの名前が更新される場合について考えます。これは、セキュリティにまったく影響を与えない決定です。 ユーザー プリンシパルを非破壊的に更新したい場合は、context.ReplacePrincipal を呼び出し、context.ShouldRenew プロパティを true に設定します。

Warning

ここで説明するアプローチは、すべての要求でトリガーされます。 すべての要求ですべてのユーザーについて認証 cookie を検証すると、アプリのパフォーマンスが大幅に低下する可能性があります。

永続的な Cookie

cookie をブラウザー セッション間で永続化することができます。 この永続化は、サインイン時の "アカウントを記憶する" チェック ボックスや同様のメカニズムによって、ユーザーの明示的な同意がある場合にのみ有効にする必要があります。

次のコード スニペットは、ブラウザーの終了後も存続するアイデンティティと該当するcookieを作成します。 以前に構成されたスライド式有効期限の設定が尊重されます。 ブラウザーが閉じられている間に cookie の有効期限が切れると、ブラウザーの再起動時に cookie はクリアされます。

IsPersistenttrueAuthenticationProperties に設定します。

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true
    });

ExpiresUtc を使用して、絶対的な有効期限を設定できます。 永続的な cookie を作成するには、IsPersistent も設定する必要があります。 そうしないと、cookie はセッション ベースの有効期間で作成され、保持されている認証チケットの前または後に期限切れになる可能性があります。 ExpiresUtc が設定されていると、ExpireTimeSpanCookieAuthenticationOptions オプションの値が設定されている場合はオーバーライドされます。

次のコード スニペットは、20 分間続く ID と対応する cookie を作成します。 これにより、以前に構成されたスライド式有効期限の設定はすべて無視されます。

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true,
        ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
    });