Buat mekanisme login menggunakan otentikasi cookie, dan buat mekanisme untuk dialihkan jika Anda tidak diautentikasi
Lingkungan operasi
- Visual Studio
-
- Komunitas Visual Studio 2022
- ASP.NET Core (MVC, Halaman Pisau Cukur)
- 6.0
Pada awalnya
Kali ini, ASP.NET Core akan menggunakan otentikasi cookie sebagai mekanisme otentikasi login. Anda dapat menganggap otentikasi cookie mirip dengan otentikasi bentuk tradisional.
Mekanisme otentikasi lain untuk ASP.NET Core adalah ASP.NET Core Identity. Selain autentikasi menggunakan formulir, ini memungkinkan Anda untuk mengautentikasi dengan API, menggunakan layanan login eksternal, mengelola dan mengatur ulang kata sandi, dll. Anda dapat menggunakan banyak fitur. Namun, dari sudut pandang hanya membuat layar login sederhana kali ini, itu akan menjadi mekanisme otentikasi yang agak berlebihan. Kami tidak akan menggunakannya kali ini.
Dalam tips otentikasi cookie yang diperkenalkan kali ini, Anda tidak dapat menampilkan apa pun selain layar login kecuali Anda masuk. Jika Anda mencoba menavigasi ke layar lain, Anda akan diarahkan ke layar login. Jika Anda masuk, Anda dapat melihat layar lain.
Untuk saat ini, Anda dapat masuk dengan memasukkan nama pengguna dan kata sandi Anda di layar masuk. Otentikasi pengguna itu sendiri diimplementasikan sebagai tempat sementara. Dalam hal ini, fokus utamanya adalah pada penerapan otentikasi cookie, sehingga esensi dari proses penentuan seperti apakah kata sandi sudah benar bukanlah esensinya.
Tip ini hanya menjelaskan sebagian dari program. Untuk kode lengkap, unduh program lengkap. Ini juga mencakup kerangka kerja MVC dan Razor Pages.
Membuat proyek
Mulai Visual Studio dan buat proyek baru.
Untuk Razor Pages, pilih ASP.NET Core Web App, atau untuk MVC, pilih ASP.NET Core Web App (Model-View-Controller).
Tentukan nama proyek pilihan Anda dan lokasi untuk proyek tersebut.
Untuk jenis otentikasi, pilih "Tidak Ada". Jika Anda memilih autentikasi lain, Anda akan menggunakan ASP.NET Core Identity. Ketika Anda selesai dengan pengaturan, klik tombol "Buat".
Setelah membuat proyek, layar yang ditunjukkan di bawah ini akan ditampilkan saat debugging dijalankan. Kami akan membuat program berdasarkan layar ini.
Edit Program.cs (Razor Pages, MVC Common)
Tambahkan definisi yang diperlukan untuk otentikasi cookie ke Program.cs. Ruang nama yang akan ditambahkan adalah sebagai berikut:
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
Berikut kode builder.Services
untuk ditambahkan ke .
// === 省略 ===
// 「Razor Pages」のコード
// builder.Services.AddRazorPages();
// 「MVC」のコード
// builder.Services.AddControllersWithViews();
// ※ここから追加
// Cookie による認証スキームを追加する
builder.Services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
builder.Services.AddAuthorization(options =>
{
// AllowAnonymous 属性が指定されていないすべての画面、アクションなどに対してユーザー認証が必要となる
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
// ※ここまで追加
var app = builder.Build();
// === 省略 ===
AddAuthentication
AddCookie
Anda dapat mengaktifkan otentikasi cookie dengan menjalankan metode dan.
Jika Anda tidak perlu mengubah nama skema, CookieAuthenticationDefaults.AuthenticationScheme
tentukan .
AddAuthorization
Jika Anda options.FallbackPolicy
RequireAuthenticatedUser
menentukan untuk metode ini
Anda dapat menerapkan kebijakan yang diperlukan autentikasi ke semua halaman, semua pengontrol, dan tindakan.
Jika Anda ingin meminta otentikasi untuk apa pun selain layar login, ini adalah metode yang berguna dalam hal mengurangi kode dan mencegah kesalahan dalam deskripsi.
Anda harus menulis kode yang tidak memerlukan otentikasi untuk layar login secara terpisah.
Berikut ini adalah app
kode untuk .
// === 省略 ===
app.UseRouting();
app.UseAuthentication(); // [追加] 認証
app.UseAuthorization(); // 認可
// 「Razor Pages」のコード
// app.MapRazorPages();
// 「MVC」のコード
// app.MapControllerRoute(
// name: "default",
// pattern: "{controller=Home}/{action=Index}/{id?}");
// === 省略 ===
Karena kita ingin menambahkan fungsionalitas otentikasi ke aplikasi, app.UseAuthentication()
kita akan menambahkan file .
Deskripsi lokasi sesuai dengan dokumentasi MSDN, aplikasi. UseAuthorization().
Selain itu, ini masih template.
Program untuk proyek Razor Pages
Membuat halaman login (Pages/Account/Login.cshtml.cs)
Membuat file
Buat halaman login. Jalur file harus dibuat sebagai "/Pages/Account/Login.cshtml".
Ini karena jalur login default seperti itu.
Jika Anda ingin mengubah jalur ini, Anda Program.cs
dapat melakukannya dengan mengatur argumen metode AddCookie
.
Anda dapat membuatnya dengan menyalin file lain alih-alih membuatnya dari menu, tetapi dalam hal ini, harap perbaiki program dengan benar.
Izinkan pengguna mengakses halaman login tanpa login
Program.cs
Karena semua halaman hanya dapat diakses ketika Anda masuk, Anda hanya perlu mengatur halaman masuk sehingga Anda dapat mengaksesnya bahkan jika Anda tidak masuk.
AllowAnonymous
Dengan menambahkan atribut, halaman target dapat diakses meskipun tidak diautentikasi.
AllowAnonymous
Atribut dapat digunakan di tempat lain selain layar login, seperti operasi API yang tidak terkait dengan autentikasi cookie.
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Security.Claims;
namespace AspNetCoreCookieAuthenticationRazorPages.Pages.Account
{
[AllowAnonymous]
public class LoginModel : PageModel
{
}
}
Membuat variabel untuk menerima input
Ketika Anda masuk, Anda menyatakan nama pengguna Anda untuk dapat menerima nilai-nilai tersebut karena Anda memasukkan kata sandi Anda.
// 省略
[AllowAnonymous]
public class LoginModel : PageModel
{
<summary>ユーザー名。</summary>
[BindProperty]
[Required]
[DisplayName("ユーザー名")]
public string UserName { get; set; } = "";
<summary>パスワード。</summary>
[BindProperty]
[Required]
[DataType(DataType.Password)]
[DisplayName("パスワード")]
public string Password { get; set; } = "";
}
Tentukan nama pengguna dan kata sandi untuk autentikasi masuk
Awalnya, itu akan disimpan dalam database, dll., Tetapi karena penilaian pengguna bukan fokus utama kali ini, saya akan menjadikannya sebagai tempat sementara.
// 省略
[AllowAnonymous]
public class LoginModel : PageModel
{
// 省略
<summary>仮のユーザーデータベースとする。</summary>
private Dictionary<string, string> UserAccounts { get; set; } = new Dictionary<string, string>
{
{ "user1", "password1" },
{ "user2", "password2" },
};
}
Proses login
<summary>ログイン処理。</summary>
public async Task<ActionResult> OnPost()
{
// 入力内容にエラーがある場合は処理を中断してエラー表示
if (ModelState.IsValid == false) return Page();
// ユーザーの存在チェックとパスワードチェック (仮実装)
// 本 Tips は Cookie 認証ができるかどうかの確認であるため入力内容やパスワードの厳密なチェックは行っていません
if (UserAccounts.TryGetValue(UserName, out string? getPass) == false || Password != getPass)
{
ModelState.AddModelError("", "ユーザー名またはパスワードが一致しません。");
return Page();
}
// サインインに必要なプリンシパルを作る
var claims = new[] { new Claim(ClaimTypes.Name, UserName) };
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
// 認証クッキーをレスポンスに追加
await HttpContext.SignInAsync(principal);
// ログインが必要な画面にリダイレクトします
return RedirectToPage("/Index");
}
Ini adalah proses otentikasi setelah menekan tombol login. Jika nama pengguna dan kata sandi cocok, autentikasi dimungkinkan.
Kode yang dijelaskan adalah kode minimum yang diperlukan untuk autentikasi,Claim
ClaimsIdentity
ClaimsPrincipal
dan
HttpContext.SignInAsync
Dengan memanggil metode, cookie dihasilkan dan diautentikasi.
Jika klaim tambahan diperlukan atau kedaluwarsa cookie diperlukan, parameter tambahan ditambahkan.
Setelah masuk, Anda akan diarahkan ke , di mana /Index
otentikasi diperlukan.
Proses logout
<summary>ログアウト処理。</summary>
public async Task OnGetLogout()
{
// 認証クッキーをレスポンスから削除
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
Logout
Ketika diakses dengan handler, diproses untuk log out.
HttpContext.SignOutAsync
Dengan memanggil metode ini, Anda dapat menghapus cookie dan mengembalikannya ke keadaan di mana Anda tidak masuk.
Membuat Tampilan
Kami tidak memperhitungkan penampilan. Tambahkan bidang untuk memasukkan nama pengguna dan kata sandi Anda seperti yang ditunjukkan di bawah ini, dan tempatkan tombol untuk masuk.
Anda juga harus memiliki tautan ke akses tanpa masuk untuk /Index
pengujian.
Karena sulit untuk memasukkan nama pengguna dan kata sandi, nilai awal ditetapkan.
@page
@model AspNetCoreCookieAuthenticationRazorPages.Pages.Account.LoginModel
@{}
<form asp-action="Login">
<div class="row m-1 g-3">
<div class="col-sm-6 offset-sm-3">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
</div>
</div>
<div class="row m-1 g-3">
<div class="col-sm-6 offset-sm-3">
<label asp-for="UserName" class="form-label"></label>
<input asp-for="UserName" class="form-control" value="user1" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
</div>
<div class="row m-1 g-3">
<div class="col-sm-6 offset-sm-3">
<label asp-for="Password" class="form-label"></label>
<input asp-for="Password" class="form-control" value="password1" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
</div>
<div class="row m-1 g-3">
<div class="col-sm-6 offset-sm-3">
<button type="submit" class="btn btn-primary">ログイン</button>
</div>
</div>
<div class="row m-1 g-3">
<div class="col-sm-6 offset-sm-3">
<a asp-page="/Index">認証が必要な画面へ直接リンク</a>
</div>
</div>
</form>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
Membuat tautan keluar (/Pages/Shared/_Layout.cshtml)
Kami tidak akan membuat perubahan apa pun pada layar beranda, tetapi kami akan menempatkan tautan keluar di bilah navigasi. Juga, untuk pengujian, posting tautan yang membawa Anda ke layar masuk tanpa keluar.
<!-- 中略 -->
<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>
<!-- ここから追加 -->
<li class="nav-item">
<a class="nav-link text-dark" asp-page="/Account/Login" asp-page-handler="Logout">ログアウト</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-page="/Account/Login">ログアウトせずログインへ</a>
</li>
<!-- ここまで追加 -->
</ul>
</div>
<!-- 中略 -->
Itu saja untuk kode Razor Pages.
Program untuk Proyek MVC
Membuat Model Login
Anda telah membuat model untuk menerima nilai yang dimasukkan pada layar login.
namespace AspNetCoreCookieAuthenticationMvc.Models
{
public class LoginModel
{
<summary>ユーザー名。</summary>
[Required]
[DisplayName("ユーザー名")]
public string UserName { get; set; } = "";
<summary>パスワード。</summary>
[Required]
[DataType(DataType.Password)]
[DisplayName("パスワード")]
public string Password { get; set; } = "";
}
}
Membuat AccountController
Buat pengontrol dan tindakan yang diperlukan untuk membuat layar login.
Buat nama AccountController
pengontrol sebagai .
Ini karena secara default, nama pengontrol dan nama tindakan pada layar login diatur ke "~/Account/Login".
Jika Anda ingin mengubah jalur ini, Anda dapat melakukannya dalam opsi AddCookie
metode di Program.cs.
Untuk saat ini, kami akan melanjutkan dengan pengaturan default.
Pertama, mari kita buat sisi Controller.
using AspNetCoreCookieAuthenticationMvc.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
namespace AspNetCoreCookieAuthenticationMvc.Controllers
{
<remarks>
<see cref="AllowAnonymous"/> 属性は Cookie 認証していなくてもアクセスできる Action (Controller) であることを示す。
</remarks>
[AllowAnonymous]
public class AccountController : Controller
{
}
}
AllowAnonymous
Dengan memberikan atribut, semua tindakan di dalamnya dapat dilakukan tanpa diautentikasi.
Ini memungkinkan Anda untuk mengakses hanya layar login tanpa otentikasi.
AllowAnonymous
Atribut juga dapat digunakan dalam pengontrol khusus API yang tidak terkait dengan otentikasi cookie di tempat lain selain layar login.
Selanjutnya, tentukan pengguna dan kata sandi yang dapat masuk. Awalnya, itu akan disimpan dalam database, dll., Tetapi karena penilaian pengguna bukan fokus utama kali ini, saya akan menjadikannya sebagai tempat sementara.
[AllowAnonymous]
public class AccountController : Controller
{
<summary>仮のユーザーデータベースとする。</summary>
private Dictionary<string, string> UserAccounts { get; set; } = new Dictionary<string, string>
{
{ "user1", "password1" },
{ "user2", "password2" },
};
}
Berikut ini adalah tindakan yang menampilkan layar login. Karena hanya ditampilkan, ia mengembalikan tampilan apa adanya.
<summary>ログイン画面を表示します。</summary>
public IActionResult Login() => View();
Di bawah ini adalah kode yang akan diproses saat masuk.
<summary>ログイン処理を実行します。</summary>
[HttpPost]
public async Task<IActionResult> Login(LoginModel model)
{
// 入力内容にエラーがある場合は処理を中断してエラー表示
if (ModelState.IsValid == false) return View(model);
// ユーザーの存在チェックとパスワードチェック (仮実装)
// 本 Tips は Cookie 認証ができるかどうかの確認であるため入力内容やパスワードの厳密なチェックは行っていません
if (UserAccounts.TryGetValue(model.UserName, out string? getPass) == false || model.Password != getPass)
{
ModelState.AddModelError("", "ユーザー名またはパスワードが一致しません。");
return View(model);
}
// サインインに必要なプリンシパルを作る
var claims = new[] { new Claim(ClaimTypes.Name, model.UserName) };
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
// 認証クッキーをレスポンスに追加
await HttpContext.SignInAsync(principal);
// ログインが必要な画面にリダイレクトします
return RedirectToAction(nameof(HomeController.Index), "Home");
}
Ini adalah proses otentikasi setelah menekan tombol login. Jika nama pengguna dan kata sandi cocok, autentikasi dimungkinkan.
Kode yang dijelaskan adalah kode minimum yang diperlukan untuk autentikasi,Claim
ClaimsIdentity
ClaimsPrincipal
dan
HttpContext.SignInAsync
Dengan memanggil metode, cookie dihasilkan dan diautentikasi.
Jika klaim tambahan diperlukan atau kedaluwarsa cookie diperlukan, parameter tambahan ditambahkan.
Setelah masuk, Anda akan diarahkan ke , di mana ~/Home/Index
otentikasi diperlukan.
Akhirnya, proses logout ditambahkan.
<summary>ログアウト処理を実行します。</summary>
public async Task<IActionResult> Logout()
{
// 認証クッキーをレスポンスから削除
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// ログイン画面にリダイレクト
return RedirectToAction(nameof(Login));
}
HttpContext.SignOutAsync
Dengan memanggil metode ini, Anda dapat menghapus cookie dan mengembalikannya ke keadaan di mana Anda tidak masuk.
Membuat tampilan (formulir login) (/Views/Account/Login.cshtml)
Login
Klik kanan tindakan untuk menambahkan tampilan. Anda juga dapat membuatnya dengan menyalinnya dari file lain.
Kami tidak memperhitungkan penampilan. Tambahkan bidang untuk memasukkan nama pengguna dan kata sandi Anda seperti yang ditunjukkan di bawah ini, dan tempatkan tombol untuk masuk.
Anda juga harus memiliki tautan ke akses tanpa masuk untuk Home/Index
pengujian.
Karena sulit untuk memasukkan nama pengguna dan kata sandi, nilai awal ditetapkan.
@model LoginModel
@{}
<form asp-action="Login">
<div class="row m-1 g-3">
<div class="col-sm-6 offset-sm-3">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
</div>
</div>
<div class="row m-1 g-3">
<div class="col-sm-6 offset-sm-3">
<label asp-for="UserName" class="form-label"></label>
<input asp-for="UserName" class="form-control" value="user1" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
</div>
<div class="row m-1 g-3">
<div class="col-sm-6 offset-sm-3">
<label asp-for="Password" class="form-label"></label>
<input asp-for="Password" class="form-control" value="password1" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
</div>
<div class="row m-1 g-3">
<div class="col-sm-6 offset-sm-3">
<button type="submit" class="btn btn-primary">ログイン</button>
</div>
</div>
<div class="row m-1 g-3">
<div class="col-sm-6 offset-sm-3">
<a asp-controller="Home" asp-action="Index">認証が必要な画面へ直接リンク</a>
</div>
</div>
</form>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
Membuat tautan keluar (/Views/Shared/_Layout.cshtml)
Kami tidak akan membuat perubahan apa pun pada layar beranda, tetapi kami akan menempatkan tautan keluar di bilah navigasi. Juga, untuk pengujian, posting tautan yang membawa Anda ke layar masuk tanpa keluar.
<!-- 中略 -->
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
<!-- ここから追加 -->
<li class="nav-item">
<a class="nav-link text-dark" asp-controller="Account" asp-action="Logout">ログアウト</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-controller="Account" asp-action="Login">ログアウトせずログインへ</a>
</li>
<!-- ここまで追加 -->
</ul>
</div>
<!-- 中略 -->
Itu saja untuk kode MVC.
Konfirmasi operasi
Ini melengkapi penerapan autentikasi cookie minimum yang diperlukan. Coba jalankan dan lihat cara kerjanya. Perilaku harus berubah tergantung pada apakah Anda login atau tidak. Sebagai contoh sederhana, Anda dapat melihat perilaku berikut.
Operasi | ⇒ | hasil operasi |
---|---|---|
Pulang tanpa login | ⇒ | Redirect ke layar login |
Login | ⇒ | Membuka layar beranda |
Keluar dari rumah dan pulang tanpa masuk | ⇒ | Redirect ke layar login |
Pulang tanpa keluar dari rumah dan masuk | ⇒ | Membuka layar beranda |