Menggunakan cookie autentikasi tanpa ASP.NET Core Identity

Oleh Rick Anderson

ASP.NET Core Identity adalah penyedia autentikasi lengkap dan berfungsi lengkap untuk membuat dan memelihara login. Namun, penyedia autentikasi cookieberbasis tanpa ASP.NET Core Identity dapat digunakan. Untuk informasi selengkapnya, lihat Pengantar Identity ASP.NET Core.

Melihat atau mengunduh kode sampel (cara mengunduh)

Untuk tujuan demonstrasi di aplikasi sampel, akun pengguna untuk pengguna hipotetis, Maria Rodriguez, dikodekan secara permanen ke dalam aplikasi. Gunakan Alamat maria.rodriguez@contoso.com email dan kata sandi apa pun untuk memasukkan pengguna. Pengguna diautentikasi dalam AuthenticateUser metode dalam Pages/Account/Login.cshtml.cs file. Dalam contoh dunia nyata, pengguna akan diautentikasi terhadap datastore.

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 diteruskan untuk AddAuthentication mengatur skema autentikasi default untuk aplikasi. AuthenticationScheme berguna ketika ada beberapa instans cookie autentikasi dan aplikasi perlu mengotorisasi dengan skema tertentu. AuthenticationScheme Mengatur ke CookieAuthenticationDefaults.AuthenticationScheme memberikan nilai "Cookies" untuk skema. Nilai string apa pun dapat digunakan yang membedakan skema.

Skema autentikasi aplikasi berbeda dari skema autentikasi aplikasi cookie . Ketika skema autentikasi cookie tidak disediakan untuk AddCookie, skema tersebut menggunakan CookieAuthenticationDefaults.AuthenticationScheme. Sumber CookieAuthenticationDefaults.AuthenticationScheme GitHub menunjukkan diatur ke "Cookies".

Properti autentikasi cookieIsEssential diatur ke true secara default. Autentikasi cookiediizinkan ketika pengunjung situs belum menyetujui pengumpulan data. Untuk informasi selengkapnya, lihat Dukungan Peraturan Perlindungan Data Umum (GDPR) di ASP.NET Core.

Kelas CookieAuthenticationOptions digunakan untuk mengonfigurasi opsi penyedia autentikasi.

Konfigurasikan CookieAuthenticationOptionsAddCookie dalam metode :

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 Middleware Kebijakan (Sumber GitHub)UseCookiePolicy memungkinkan cookie kemampuan kebijakan. Middleware diproses dalam urutan ditambahkan:

app.UseCookiePolicy(cookiePolicyOptions);

Gunakan CookiePolicyOptions yang disediakan untuk Cookie Middleware Kebijakan untuk mengontrol karakteristik cookie global pemrosesan dan kait ke cookie penghandel pemrosesan saat cookieditambahkan atau dihapus.

Nilai defaultnya MinimumSameSitePolicy adalah SameSiteMode.Lax mengizinkan autentikasi OAuth2. Untuk menerapkan kebijakan situs yang sama secara ketat dari SameSiteMode.Strict, atur MinimumSameSitePolicy. Meskipun pengaturan ini melanggar OAuth2 dan skema autentikasi lintas asal lainnya, pengaturan ini meningkatkan tingkat cookie keamanan untuk jenis aplikasi lain yang tidak bergantung pada pemrosesan permintaan lintas asal.

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

Pengaturan Cookie Middleware Kebijakan untuk MinimumSameSitePolicy dapat memengaruhi pengaturan Cookie.SameSite dalam CookieAuthenticationOptions sesuai dengan matriks di bawah ini.

MinimumSameSitePolicy Cookie. SameSite Hasil . Cookie Pengaturan 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

Untuk membuat cookie informasi pengguna penahanan, buat ClaimsPrincipal. Informasi pengguna diserialisasikan dan disimpan di cookie.

ClaimsIdentity Buat dengan s dan panggilan SignInAsync yang diperlukan Claimuntuk masuk ke pengguna. Login.cshtml.cs dalam aplikasi sampel berisi kode berikut:

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();
}

Jika Anda ingin melihat komentar kode yang diterjemahkan ke bahasa selain bahasa Inggris, beri tahu kami dalam masalah diskusi GitHub ini.

SignInAsync membuat terenkripsi cookie dan menambahkannya ke respons saat ini. Jika AuthenticationScheme tidak ditentukan, skema default digunakan.

RedirectUri hanya digunakan pada beberapa jalur tertentu secara default, misalnya, jalur masuk dan jalur keluar. Untuk informasi selengkapnya, lihat Cookiesumber AuthenticationHandler.

sistem Perlindungan Data ASP.NET Core digunakan untuk enkripsi. Untuk aplikasi yang dihosting di beberapa komputer, penyeimbangan beban di seluruh aplikasi, atau menggunakan farm web, konfigurasikan perlindungan data untuk menggunakan cincin kunci dan pengidentifikasi aplikasi yang sama.

Keluar

Untuk mengeluarkan pengguna saat ini dan menghapus , cookiepanggil 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;
}

Jika CookieAuthenticationDefaults.AuthenticationScheme atau "Cookies" tidak digunakan sebagai skema, berikan skema yang digunakan saat mengonfigurasi penyedia autentikasi. Jika tidak, skema default digunakan. Misalnya, jika "ContosoCookie" digunakan sebagai skema, berikan skema yang digunakan saat mengonfigurasi penyedia autentikasi.

Ketika browser menutupnya secara otomatis menghapus sesi berbasis cookie(non-persisten cookie), tetapi tidak ada cookieyang dibersihkan ketika tab individual ditutup. Server tidak diberi tahu tentang tab atau browser menutup peristiwa.

Bereaksi terhadap perubahan back-end

cookie Setelah dibuat, cookie adalah sumber identitas tunggal. Jika akun pengguna dinonaktifkan di sistem back-end:

  • Sistem autentikasi aplikasi cookie terus memproses permintaan berdasarkan autentikasi cookie.
  • Pengguna tetap masuk ke aplikasi selama autentikasi cookie valid.

Kejadian ini ValidatePrincipal dapat digunakan untuk mencegat dan mengambil alih validasi cookie identitas. Memvalidasi cookie pada setiap permintaan mengurangi risiko pengguna yang dicabut mengakses aplikasi.

Salah satu pendekatan validasi cookie didasarkan pada melacak kapan database pengguna berubah. Jika database belum diubah sejak pengguna cookie dikeluarkan, tidak perlu mengautentikasi ulang pengguna jika mereka cookie masih valid. Di aplikasi sampel, database diimplementasikan di IUserRepository dan menyimpan LastChanged nilai. Saat pengguna diperbarui dalam database, LastChanged nilai diatur ke waktu saat ini.

Untuk membatalkan validasi cookie saat database berubah berdasarkan LastChanged nilai, buat cookie dengan klaim yang LastChanged berisi nilai saat ini LastChanged dari database:

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));

Untuk menerapkan penimpaan untuk peristiwa tersebut ValidatePrincipal , tulis metode dengan tanda tangan berikut di kelas yang berasal dari CookieAuthenticationEvents:

ValidatePrincipal(CookieValidatePrincipalContext)

Berikut ini adalah contoh implementasi dari 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);
        }
    }
}

Daftarkan instans peristiwa selama cookie pendaftaran layanan. Berikan pendaftaran layanan terlingkup untuk kelas Anda 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();

Pertimbangkan situasi di mana nama pengguna diperbarui—keputusan yang tidak memengaruhi keamanan dengan cara apa pun. Jika Anda ingin memperbarui prinsipal pengguna secara non-destruktif, panggil context.ReplacePrincipal dan atur context.ShouldRenew properti ke true.

Peringatan

Pendekatan yang dijelaskan di sini dipicu pada setiap permintaan. Memvalidasi autentikasi cookieuntuk semua pengguna pada setiap permintaan dapat mengakibatkan penalti performa besar untuk aplikasi.

Persisten cookies

Anda mungkin ingin cookie bertahan di seluruh sesi browser. Persistensi ini hanya boleh diaktifkan dengan persetujuan pengguna eksplisit dengan kotak centang "Ingat Saya" saat masuk atau mekanisme serupa.

Cuplikan kode berikut menciptakan identitas dan yang sesuai cookie yang bertahan melalui penutupan browser. Setiap pengaturan kedaluwarsa geser yang sebelumnya dikonfigurasi akan dihormati. Jika kedaluwarsa cookie saat browser ditutup, browser akan menghapus cookie setelah dimulai ulang.

Atur IsPersistent ke true dalam AuthenticationProperties:

// using Microsoft.AspNetCore.Authentication;

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

Waktu kedaluwarsa absolut dapat diatur dengan ExpiresUtc. Untuk membuat persisten cookie, IsPersistent juga harus diatur. Jika tidak, cookie dibuat dengan masa pakai berbasis sesi dan dapat kedaluwarsa baik sebelum atau sesudah tiket autentikasi yang disimpannya. Ketika ExpiresUtc diatur, itu mengambil alih nilai ExpireTimeSpan opsi CookieAuthenticationOptions, jika diatur.

Cuplikan kode berikut membuat identitas dan sesuai cookie yang berlangsung selama 20 menit. Ini mengabaikan pengaturan kedaluwarsa geser yang sebelumnya dikonfigurasi.

// 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 adalah penyedia autentikasi lengkap dan berfungsi lengkap untuk membuat dan memelihara login. Namun, penyedia autentikasi cookieberbasis tanpa ASP.NET Core Identity dapat digunakan. Untuk informasi selengkapnya, lihat Pengantar Identity ASP.NET Core.

Melihat atau mengunduh kode sampel (cara mengunduh)

Untuk tujuan demonstrasi di aplikasi sampel, akun pengguna untuk pengguna hipotetis, Maria Rodriguez, dikodekan secara permanen ke dalam aplikasi. Gunakan Alamat maria.rodriguez@contoso.com email dan kata sandi apa pun untuk memasukkan pengguna. Pengguna diautentikasi dalam AuthenticateUser metode dalam Pages/Account/Login.cshtml.cs file. Dalam contoh dunia nyata, pengguna akan diautentikasi terhadap database.

Konfigurasi

Dalam metode , Startup.ConfigureServices buat layanan Middleware Autentikasi dengan AddAuthentication metode dan AddCookie :

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

AuthenticationScheme diteruskan untuk AddAuthentication mengatur skema autentikasi default untuk aplikasi. AuthenticationScheme berguna ketika ada beberapa instans cookie autentikasi dan Anda ingin mengotorisasi dengan skema tertentu. AuthenticationScheme Mengatur ke CookieAuthenticationDefaults.AuthenticationScheme memberikan nilai "Cookies" untuk skema. Anda dapat menyediakan nilai string apa pun yang membedakan skema.

Skema autentikasi aplikasi berbeda dari skema autentikasi aplikasi cookie . Ketika skema autentikasi cookie tidak disediakan untuk AddCookie, skema menggunakan CookieAuthenticationDefaults.AuthenticationScheme ("Cookies").

Properti autentikasi cookieIsEssential diatur ke true secara default. Autentikasi cookiediizinkan ketika pengunjung situs belum menyetujui pengumpulan data. Untuk informasi selengkapnya, lihat Dukungan Peraturan Perlindungan Data Umum (GDPR) di ASP.NET Core.

Di Startup.Configure, panggil UseAuthentication dan UseAuthorization untuk mengatur HttpContext.User properti dan menjalankan Middleware Otorisasi untuk permintaan. UseAuthentication Panggil metode dan UseAuthorization sebelum memanggil UseEndpoints:

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

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

Kelas CookieAuthenticationOptions digunakan untuk mengonfigurasi opsi penyedia autentikasi.

Atur CookieAuthenticationOptions dalam konfigurasi layanan untuk autentikasi dalam Startup.ConfigureServices metode :

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

Cookie Middleware Kebijakan memungkinkan cookie kemampuan kebijakan. Menambahkan middleware ke alur pemrosesan aplikasi bersifat sensitif terhadap pesanan—hanya memengaruhi komponen hilir yang terdaftar dalam alur.

app.UseCookiePolicy(cookiePolicyOptions);

Gunakan CookiePolicyOptions yang disediakan untuk Cookie Middleware Kebijakan untuk mengontrol karakteristik cookie global pemrosesan dan kait ke cookie penghandel pemrosesan saat cookieditambahkan atau dihapus.

Nilai defaultnya MinimumSameSitePolicy adalah SameSiteMode.Lax mengizinkan autentikasi OAuth2. Untuk menerapkan kebijakan situs yang sama secara ketat dari SameSiteMode.Strict, atur MinimumSameSitePolicy. Meskipun pengaturan ini melanggar OAuth2 dan skema autentikasi lintas asal lainnya, pengaturan ini meningkatkan tingkat cookie keamanan untuk jenis aplikasi lain yang tidak bergantung pada pemrosesan permintaan lintas asal.

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

Pengaturan Cookie Middleware Kebijakan untuk MinimumSameSitePolicy dapat memengaruhi pengaturan Cookie.SameSite dalam CookieAuthenticationOptions sesuai dengan matriks di bawah ini.

MinimumSameSitePolicy Cookie. SameSite Hasil . Cookie Pengaturan 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

Untuk membuat cookie informasi pengguna penahanan, buat ClaimsPrincipal. Informasi pengguna diserialisasikan dan disimpan di cookie.

ClaimsIdentity Buat dengan s dan panggilan SignInAsync yang diperlukan Claimuntuk masuk ke pengguna:

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);

Jika Anda ingin melihat komentar kode yang diterjemahkan ke bahasa selain bahasa Inggris, beri tahu kami dalam masalah diskusi GitHub ini.

SignInAsync membuat terenkripsi cookie dan menambahkannya ke respons saat ini. Jika AuthenticationScheme tidak ditentukan, skema default digunakan.

RedirectUri hanya digunakan pada beberapa jalur tertentu secara default, misalnya, jalur masuk dan jalur keluar. Untuk informasi selengkapnya, lihat Cookiesumber AuthenticationHandler.

sistem Perlindungan Data ASP.NET Core digunakan untuk enkripsi. Untuk aplikasi yang dihosting di beberapa komputer, penyeimbangan beban di seluruh aplikasi, atau menggunakan farm web, konfigurasikan perlindungan data untuk menggunakan cincin kunci dan pengidentifikasi aplikasi yang sama.

Keluar

Untuk mengeluarkan pengguna saat ini dan menghapus , cookiepanggil SignOutAsync:

await HttpContext.SignOutAsync(
    CookieAuthenticationDefaults.AuthenticationScheme);

Jika CookieAuthenticationDefaults.AuthenticationScheme (atau "Cookies") tidak digunakan sebagai skema (misalnya, "ContosoCookie"), berikan skema yang digunakan saat mengonfigurasi penyedia autentikasi. Jika tidak, skema default digunakan.

Ketika browser menutupnya secara otomatis menghapus sesi berbasis cookie(non-persisten cookie), tetapi tidak ada cookieyang dibersihkan ketika tab individual ditutup. Server tidak diberi tahu tentang tab atau browser menutup peristiwa.

Bereaksi terhadap perubahan back-end

cookie Setelah dibuat, cookie adalah sumber identitas tunggal. Jika akun pengguna dinonaktifkan di sistem back-end:

  • Sistem autentikasi aplikasi cookie terus memproses permintaan berdasarkan autentikasi cookie.
  • Pengguna tetap masuk ke aplikasi selama autentikasi cookie valid.

Kejadian ini ValidatePrincipal dapat digunakan untuk mencegat dan mengambil alih validasi cookie identitas. Memvalidasi cookie pada setiap permintaan mengurangi risiko pengguna yang dicabut mengakses aplikasi.

Salah satu pendekatan validasi cookie didasarkan pada melacak kapan database pengguna berubah. Jika database belum diubah sejak pengguna cookie dikeluarkan, tidak perlu mengautentikasi ulang pengguna jika mereka cookie masih valid. Di aplikasi sampel, database diimplementasikan di IUserRepository dan menyimpan LastChanged nilai. Saat pengguna diperbarui dalam database, LastChanged nilai diatur ke waktu saat ini.

Untuk membatalkan validasi cookie saat database berubah berdasarkan LastChanged nilai, buat cookie dengan klaim yang LastChanged berisi nilai saat ini LastChanged dari database:

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));

Untuk menerapkan penimpaan untuk peristiwa tersebut ValidatePrincipal , tulis metode dengan tanda tangan berikut di kelas yang berasal dari CookieAuthenticationEvents:

ValidatePrincipal(CookieValidatePrincipalContext)

Berikut ini adalah contoh implementasi dari 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);
        }
    }
}

Daftarkan instans peristiwa selama cookie pendaftaran layanan dalam Startup.ConfigureServices metode . Berikan pendaftaran layanan terlingkup untuk kelas Anda CustomCookieAuthenticationEvents :

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

services.AddScoped<CustomCookieAuthenticationEvents>();

Pertimbangkan situasi di mana nama pengguna diperbarui—keputusan yang tidak memengaruhi keamanan dengan cara apa pun. Jika Anda ingin memperbarui prinsipal pengguna secara non-destruktif, panggil context.ReplacePrincipal dan atur context.ShouldRenew properti ke true.

Peringatan

Pendekatan yang dijelaskan di sini dipicu pada setiap permintaan. Memvalidasi autentikasi cookieuntuk semua pengguna pada setiap permintaan dapat mengakibatkan penalti performa besar untuk aplikasi.

Persisten cookies

Anda mungkin ingin cookie bertahan di seluruh sesi browser. Persistensi ini hanya boleh diaktifkan dengan persetujuan pengguna eksplisit dengan kotak centang "Ingat Saya" saat masuk atau mekanisme serupa.

Cuplikan kode berikut menciptakan identitas dan yang sesuai cookie yang bertahan melalui penutupan browser. Setiap pengaturan kedaluwarsa geser yang sebelumnya dikonfigurasi akan dihormati. Jika kedaluwarsa cookie saat browser ditutup, browser akan menghapus cookie setelah dimulai ulang.

Atur IsPersistent ke true dalam AuthenticationProperties:

// using Microsoft.AspNetCore.Authentication;

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

Waktu kedaluwarsa absolut dapat diatur dengan ExpiresUtc. Untuk membuat persisten cookie, IsPersistent juga harus diatur. Jika tidak, cookie dibuat dengan masa pakai berbasis sesi dan dapat kedaluwarsa baik sebelum atau sesudah tiket autentikasi yang disimpannya. Ketika ExpiresUtc diatur, itu mengambil alih nilai ExpireTimeSpan opsi CookieAuthenticationOptions, jika diatur.

Cuplikan kode berikut membuat identitas dan sesuai cookie yang berlangsung selama 20 menit. Ini mengabaikan pengaturan kedaluwarsa geser yang sebelumnya dikonfigurasi.

// using Microsoft.AspNetCore.Authentication;

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