ASP.NET Core Identity を使用せずに cookie 認証を使用する
作成者: Rick Anderson
ASP.NET Core Identity は、ログインを作成および管理するための、完全な機能を備えた認証プロバイダーです。 ただし、ASP.NET Core Identity を使用しない cookie ベースの認証プロバイダーを使用することができます。 詳細については、「ASP.NET Core の Identity の概要」を参照してください。
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
サンプル アプリでのデモンストレーションのため、架空のユーザー Maria Rodriguez のユーザー アカウントがアプリにハードコーディングされています。 メール アドレス maria.rodriguez@contoso.com
と任意のパスワードを使用して、ユーザーにサインインします。 ユーザーは、Pages/Account/Login.cshtml.cs
ファイルの AuthenticateUser
メソッドで認証されます。 実際の例では、ユーザーはデータストアに対して認証されます。
cookie 認証を追加する
- AddAuthentication および AddCookie メソッドを使って認証ミドルウェア サービスを追加します。
- UseAuthentication と UseAuthorization を呼び出して
HttpContext.User
プロパティを設定し、認可ミドルウェアを要求に応じて実行します。UseAuthentication
とUseAuthorization
は MapRazorPages や MapDefaultControllerRoute などのMap
メソッドの前に呼び出す必要があります。
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();
AddAuthentication
に渡される AuthenticationScheme によって、アプリの既定の認証方式が設定されます。 AuthenticationScheme
は、cookie 認証の複数のインスタンスがあり、アプリで特定の方式の承認を行う必要がある場合に便利です。 AuthenticationScheme
を CookieAuthenticationDefaults.AuthenticationScheme に設定すると、スキームの値は "Cookies"
になります。 スキームを区別する任意の文字列値を使用できます。
アプリの認証方式は、アプリの cookie 認証方式とは異なります。 AddCookie に cookie の認証スキームが提供されていない場合は、CookieAuthenticationDefaults.AuthenticationScheme
が使われます。 CookieAuthenticationDefaults.AuthenticationScheme
GitHub ソースは、"Cookies"
に設定されている例です。
認証 cookie の IsEssential プロパティは、既定で true
に設定されます。 サイト ビジターがデータ収集に同意していない場合、認証 Cookie が許可されます。 詳細については、「General Data Protection Regulation (GDPR) support in ASP.NET Core」(ASP.NET Core での一般データ保護規則 (GDPR) のサポート) をご覧ください。
認証プロバイダーのオプションを構成するには、CookieAuthenticationOptions クラスを使用します。
メソッド AddCookie で CookieAuthenticationOptions を構成します。
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 ポリシー ミドルウェア
Cookie ポリシー ミドルウェア (GitHub ソース) UseCookiePolicy を使うと、cookie ポリシー機能を有効にすることができます。 ミドルウェアは、追加された順序で処理されます。
app.UseCookiePolicy(cookiePolicyOptions);
cookie 処理のグローバル特性を制御し、Cookie が追加または削除されたときに cookie 処理ハンドラーにフックするには、Cookie ポリシー ミドルウェアに提供される CookiePolicyOptions を使用します。
MinimumSameSitePolicy の既定値は SameSiteMode.Lax
で、OAuth2 認証を許可します。 SameSiteMode.Strict
と同じサイト ポリシーを厳密に適用するには、MinimumSameSitePolicy
を設定します。 これを設定すると、OAuth2 や他のクロスオリジン認証方式は機能しなくなりますが、クロスオリジン要求処理に依存しない他の種類のアプリの cookie セキュリティのレベルが上がります。
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
};
MinimumSameSitePolicy
に対する Cookie ポリシー ミドルウェアの設定は、次の表に従って、CookieAuthenticationOptions
の設定における Cookie.SameSite
の設定に影響する場合があります。
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 を作成する
ユーザー情報を保持する cookie を作成するには、ClaimsPrincipal を構築します。 ユーザー情報は、シリアル化されて cookie に格納されます。
任意の必要な Claim を使用して ClaimsIdentity を作成し、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
または 「Cookie」が使用されていない場合は、認証プロバイダーを構成するときに使用するスキームを指定します。 それ以外の場合は、既定の方式が使用されます。 たとえば、スキームとして「ContosoCookie」を使用する場合は、認証プロバイダーを構成するときに使用するスキームを指定します。
ブラウザーが閉じられると、セッション ベースの cookie (非永続的な cookie) は自動的に削除されますが、個々のタブが閉じられたときは、cookie はクリアされません。 サーバーには、タブまたはブラウザーが閉じられたイベントは通知されません。
バックエンドの変更に対応する
cookie が作成されると、cookie が identity の唯一のソースになります。 バックエンド システムでユーザー アカウントが無効にされた場合:
- アプリの cookie 認証システムによる要求の処理は、認証 cookie に基づいて続けられます。
- 認証 cookie が有効である限り、ユーザーはアプリにサインインしたままになります。
ValidatePrincipal イベントを使用して、cookieidentity の検証をインターセプトし、オーバーライドすることができます。 すべての要求で cookie を検証すると、取り消されたユーザーがアプリにアクセスするリスクが軽減されます。
cookie を検証する方法の 1 つは、ユーザー データベースの変更を追跡することです。 ユーザーの cookie が発行された後でデータベースが変更されていない場合は、その cookie がまだ有効であれば、再認証を行う必要はありません。 サンプル アプリでは、データベースは IUserRepository
に実装され、そこに LastChanged
の値が格納されます。 データベースでユーザーが更新されると、LastChanged
の値に現在時刻が設定されます。
LastChanged
の値に基づいてデータベースが変更されたときに cookie を無効にするには、データベースの現在の LastChanged
の値を含む LastChanged
クレームを使用して cookie を作成します。
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
に設定します。
警告
ここで説明するアプローチは、すべての要求でトリガーされます。 すべての要求ですべてのユーザーについて認証 cookie を検証すると、アプリのパフォーマンスが大幅に低下する可能性があります。
永続的 cookie
cookie をブラウザー セッション間で永続化することができます。 この永続化は、サインイン時の "アカウントを記憶する" チェック ボックスや同様のメカニズムによって、ユーザーの明示的な同意がある場合にのみ有効にする必要があります。
次のコード スニペットでは、ブラウザーを閉じても保持される identity および対応する cookie が作成されます。 以前に構成されたスライド式有効期限の設定が尊重されます。 ブラウザーが閉じられている間に cookie の有効期限が切れると、ブラウザーの再起動時に cookie はクリアされます。
AuthenticationProperties で IsPersistent を true
に設定します。
// using Microsoft.AspNetCore.Authentication;
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = true
});
cookie の絶対的な有効期限
ExpiresUtc を使用して、絶対的な有効期限を設定できます。 永続的な cookie を作成するには、IsPersistent
も設定する必要があります。 そうしないと、cookie はセッション ベースの有効期間で作成され、保持されている認証チケットの前または後に期限切れになる可能性があります。 ExpiresUtc
が設定されていると、CookieAuthenticationOptions の ExpireTimeSpan オプションの値が設定されている場合はオーバーライドされます。
次のコード スニペットでは、有効期間が 20 分の identity および対応する 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 Identity を使用しない cookie ベースの認証プロバイダーを使用することができます。 詳細については、「ASP.NET Core の Identity の概要」を参照してください。
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
サンプル アプリでのデモンストレーションのため、架空のユーザー Maria Rodriguez のユーザー アカウントがアプリにハードコーディングされています。 メール アドレス maria.rodriguez@contoso.com
と任意のパスワードを使用して、ユーザーにサインインします。 ユーザーは、Pages/Account/Login.cshtml.cs
ファイルの AuthenticateUser
メソッドで認証されます。 現実の例では、ユーザーはデータベースに対して認証されます。
構成
Startup.ConfigureServices
メソッドでは、AddAuthentication および AddCookie メソッドを使用して認証ミドルウェア サービスが作成されます。
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
AddAuthentication
に渡される AuthenticationScheme によって、アプリの既定の認証方式が設定されます。 AuthenticationScheme
は、cookie 認証の複数のインスタンスがあり、特定の方式で承認を行う場合に便利です。 AuthenticationScheme
を CookieAuthenticationDefaults.AuthenticationScheme に設定すると、スキームに 「Cookies」の値が提供されます。 方式を区別する任意の文字列値を指定できます。
アプリの認証方式は、アプリの 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
で、UseAuthentication
と UseAuthorization
を呼び出して HttpContext.User
プロパティを設定し、要求に対して認可ミドルウェアを実行します。 UseEndpoints
を呼び出す前に、UseAuthentication
および UseAuthorization
メソッドを呼び出します。
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
認証プロバイダーのオプションを構成するには、CookieAuthenticationOptions クラスを使用します。
Startup.ConfigureServices
メソッドの認証用のサービス構成で CookieAuthenticationOptions
を設定します。
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
...
});
Cookie ポリシー ミドルウェア
Cookie ポリシー ミドルウェアを使用すると、cookie ポリシー機能が有効になります。 アプリ処理パイプラインへのミドルウェアの追加は順序に依存しており、パイプラインに登録されている下流コンポーネントにのみ影響が及びます。
app.UseCookiePolicy(cookiePolicyOptions);
cookie 処理のグローバル特性を制御し、Cookie が追加または削除されたときに cookie 処理ハンドラーにフックするには、Cookie ポリシー ミドルウェアに提供される CookiePolicyOptions を使用します。
MinimumSameSitePolicy の既定値は SameSiteMode.Lax
で、OAuth2 認証を許可します。 SameSiteMode.Strict
と同じサイト ポリシーを厳密に適用するには、MinimumSameSitePolicy
を設定します。 これを設定すると、OAuth2 や他のクロスオリジン認証方式は機能しなくなりますが、クロスオリジン要求処理に依存しない他の種類のアプリの cookie セキュリティのレベルが上がります。
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
};
MinimumSameSitePolicy
に対する Cookie ポリシー ミドルウェアの設定は、次の表に従って、CookieAuthenticationOptions
の設定における Cookie.SameSite
の設定に影響する場合があります。
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 を作成する
ユーザー情報を保持する cookie を作成するには、ClaimsPrincipal を構築します。 ユーザー情報は、シリアル化されて cookie に格納されます。
任意の必要な Claim を使用して ClaimsIdentity を作成し、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 が identity の唯一のソースになります。 バックエンド システムでユーザー アカウントが無効にされた場合:
- アプリの cookie 認証システムによる要求の処理は、認証 cookie に基づいて続けられます。
- 認証 cookie が有効である限り、ユーザーはアプリにサインインしたままになります。
ValidatePrincipal イベントを使用して、cookieidentity の検証をインターセプトし、オーバーライドすることができます。 すべての要求で cookie を検証すると、取り消されたユーザーがアプリにアクセスするリスクが軽減されます。
cookie を検証する方法の 1 つは、ユーザー データベースの変更を追跡することです。 ユーザーの cookie が発行された後でデータベースが変更されていない場合は、その cookie がまだ有効であれば、再認証を行う必要はありません。 サンプル アプリでは、データベースは IUserRepository
に実装され、そこに LastChanged
の値が格納されます。 データベースでユーザーが更新されると、LastChanged
の値に現在時刻が設定されます。
LastChanged
の値に基づいてデータベースが変更されたときに cookie を無効にするには、データベースの現在の LastChanged
の値を含む LastChanged
クレームを使用して cookie を作成します。
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);
}
}
}
Startup.ConfigureServices
メソッドで cookie サービスを登録する間にイベント インスタンスを登録します。 CustomCookieAuthenticationEvents
クラスに対してスコープ指定されたサービスの登録を提供します。
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.EventsType = typeof(CustomCookieAuthenticationEvents);
});
services.AddScoped<CustomCookieAuthenticationEvents>();
ユーザーの名前が更新される場合について考えます。これは、セキュリティにまったく影響を与えない決定です。 ユーザー プリンシパルを非破壊的に更新したい場合は、context.ReplacePrincipal
を呼び出し、context.ShouldRenew
プロパティを true
に設定します。
警告
ここで説明するアプローチは、すべての要求でトリガーされます。 すべての要求ですべてのユーザーについて認証 cookie を検証すると、アプリのパフォーマンスが大幅に低下する可能性があります。
永続的 cookie
cookie をブラウザー セッション間で永続化することができます。 この永続化は、サインイン時の "アカウントを記憶する" チェック ボックスや同様のメカニズムによって、ユーザーの明示的な同意がある場合にのみ有効にする必要があります。
次のコード スニペットでは、ブラウザーを閉じても保持される identity および対応する cookie が作成されます。 以前に構成されたスライド式有効期限の設定が尊重されます。 ブラウザーが閉じられている間に cookie の有効期限が切れると、ブラウザーの再起動時に cookie はクリアされます。
AuthenticationProperties で IsPersistent を true
に設定します。
// using Microsoft.AspNetCore.Authentication;
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = true
});
cookie の絶対的な有効期限
ExpiresUtc を使用して、絶対的な有効期限を設定できます。 永続的な cookie を作成するには、IsPersistent
も設定する必要があります。 そうしないと、cookie はセッション ベースの有効期間で作成され、保持されている認証チケットの前または後に期限切れになる可能性があります。 ExpiresUtc
が設定されていると、CookieAuthenticationOptions の ExpireTimeSpan オプションの値が設定されている場合はオーバーライドされます。
次のコード スニペットでは、有効期間が 20 分の identity および対応する 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