Opret en login-mekanisme ved hjælp af cookie-godkendelse, og opret en mekanisme, der skal omdirigeres, hvis du ikke er godkendt
Driftsmiljø
- Visual Studio
-
- Visual Studio-fællesskab 2022
- ASP.NET Core (MVC, barberbladssider)
- 6.0
Først
Denne gang bruger ASP.NET Core cookie-godkendelse som login-godkendelsesmekanisme. Du kan tænke på cookie-godkendelse som svarende til traditionel formulargodkendelse.
En anden godkendelsesmekanisme for ASP.NET Core er ASP.NET Core Identity. Ud over godkendelse ved hjælp af formularer giver dette dig mulighed for at godkende med API'er, bruge eksterne login-tjenester, administrere og nulstille adgangskoder osv. Du kan bruge mange funktioner. Men fra synspunktet om bare at oprette en simpel login-skærm denne gang, vil det være en noget overdrevet godkendelsesmekanisme. Vi vil ikke bruge det denne gang.
I de cookie-godkendelsestips, der blev introduceret denne gang, kan du ikke vise andet end loginskærmen, medmindre du logger ind. Hvis du forsøger at navigere til en anden skærm, bliver du omdirigeret til loginskærmen. Hvis du logger ind, kan du se andre skærme.
Indtil videre kan du logge ind ved at indtaste dit brugernavn og din adgangskode på loginskærmen. Selve brugergodkendelsen implementeres som et midlertidigt sted. I dette tilfælde er hovedfokus på implementeringen af cookie-godkendelse, så essensen af bestemmelsesprocessen, såsom om adgangskoden er korrekt, er ikke essensen.
Dette tip beskriver kun en del af programmet. For den komplette kode skal du downloade det komplette program. Det dækker også både MVC og Razor Pages rammer.
Oprette et projekt
Start Visual Studio, og opret et nyt projekt.
For Razor Pages skal du vælge ASP.NET Core Web App, eller for MVC skal du vælge ASP.NET Core Web App (Model-View-Controller).
Angiv et projektnavn efter eget valg og en placering til projektet.
For godkendelsestypen skal du vælge "Ingen". Hvis du vælger anden godkendelse, skal du bruge ASP.NET kerneidentitet. Når du er færdig med indstillingerne, skal du klikke på knappen "Opret".
Efter oprettelse af projektet vises skærmbilledet nedenfor, når fejlfinding udføres. Vi opretter et program baseret på denne skærm.
Rediger program.cs (barberbladssider, MVC fælles)
Føj de definitioner, der kræves til cookiegodkendelse, til Program.cs. De navneområder, der skal tilføjes, er som følger:
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
Her er builder.Services
koden, der skal føjes til .
// === 省略 ===
// 「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
Du kan aktivere cookiegodkendelse ved at udføre metoden and.
Hvis du ikke har brug for at ændre ordningens navn, CookieAuthenticationDefaults.AuthenticationScheme
skal du angive .
AddAuthorization
Hvis du options.FallbackPolicy
RequireAuthenticatedUser
angiver metoden
Du kan anvende en politik, der kræves til godkendelse, på alle sider, alle controllere og handlinger.
Hvis du vil kræve godkendelse for andet end loginskærmen, er det en nyttig metode med hensyn til at reducere koden og forhindre fejl i beskrivelsen.
Du bliver nødt til at skrive kode, der ikke kræver godkendelse til loginskærmen separat.
Følgende er app
koden for .
// === 省略 ===
app.UseRouting();
app.UseAuthentication(); // [追加] 認証
app.UseAuthorization(); // 認可
// 「Razor Pages」のコード
// app.MapRazorPages();
// 「MVC」のコード
// app.MapControllerRoute(
// name: "default",
// pattern: "{controller=Home}/{action=Index}/{id?}");
// === 省略 ===
Da vi vil tilføje godkendelsesfunktionalitet til applikationen, app.UseAuthentication()
tilføjer vi .
Beskrivelsens placering er i henhold til MSDN-dokumentationen, app. UseAuthorization().
Bortset fra det er det stadig en skabelon.
Programmer til Razor Pages-projekter
Opret en login-side (Pages/Account/Login.cshtml.cs)
Opret en fil
Opret en login-side. Filstien skal oprettes som "/Pages/Account/Login.cshtml".
Dette skyldes, at standard login-stien er sådan.
Hvis du vil ændre denne sti, kan du Program.cs
gøre det ved at angive argumentet for AddCookie
metoden til .
Du kan oprette det ved at kopiere andre filer i stedet for at oprette det fra menuen, men i så fald skal du rette programmet korrekt.
Tillad brugere at få adgang til login-siden uden at logge ind
Program.cs
Da alle sider kun kan tilgås, når du er logget ind, skal du kun indstille login-siden, så du kan få adgang til den, selvom du ikke er logget ind.
AllowAnonymous
Ved at tilføje attributter kan målsiden tilgås, selvom den ikke er godkendt.
AllowAnonymous
Attributter kan bruges andre steder end på loginskærmen, f.eks. API-handlinger, der ikke er relateret til cookiegodkendelse.
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
{
}
}
Oprette en variabel for at modtage input
Når du logger ind, erklærer du dit brugernavn for at kunne modtage disse værdier, fordi du indtaster din adgangskode.
// 省略
[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; } = "";
}
Definer et brugernavn og en adgangskode til logingodkendelse
Oprindeligt ville det blive gemt i en database osv., Men da brugervurdering ikke er hovedfokus denne gang, vil jeg gøre det som et midlertidigt sted.
// 省略
[AllowAnonymous]
public class LoginModel : PageModel
{
// 省略
<summary>仮のユーザーデータベースとする。</summary>
private Dictionary<string, string> UserAccounts { get; set; } = new Dictionary<string, string>
{
{ "user1", "password1" },
{ "user2", "password2" },
};
}
Login proces
<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");
}
Dette er godkendelsesprocessen efter at have trykket på login-knappen. Hvis brugernavnet og adgangskoden stemmer overens, er godkendelse mulig.
Den beskrevne kode er den minimumskode, der kræves til godkendelse,Claim
ClaimsIdentity
ClaimsPrincipal
og
HttpContext.SignInAsync
Ved at kalde metoden genereres og godkendes en cookie.
Hvis der kræves yderligere krav, eller cookieudløb er påkrævet, tilføjes yderligere parametre.
Når du er logget ind, omdirigeres du til , hvor /Index
godkendelse er påkrævet.
Logout proces
<summary>ログアウト処理。</summary>
public async Task OnGetLogout()
{
// 認証クッキーをレスポンスから削除
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
Logout
Når den åbnes med en handler, behandles den for at logge ud.
HttpContext.SignOutAsync
Ved at kalde metoden kan du slette cookien og returnere den til en tilstand, hvor du ikke er logget ind.
Oprettelse af en visning
Vi tager ikke hensyn til udseendet. Tilføj felter til indtastning af dit brugernavn og din adgangskode som vist nedenfor, og placer en knap for at logge ind.
Du skal også have et link til adgang uden at logge ind til /Index
test.
Da det er besværligt at indtaste brugernavn og adgangskode, indstilles startværdien.
@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"); }
}
Opret et logout-link (/Pages/Shared/_Layout.cshtml)
Vi foretager ingen ændringer på startskærmen, men vi sætter et logout-link i navigationslinjen. Til test skal du også sende et link, der fører dig til loginskærmen uden at logge ud.
<!-- 中略 -->
<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>
<!-- 中略 -->
Det er det for Razor Pages-koden.
Programmer til MVC-projekter
Oprettelse af en loginmodel
Du har oprettet en model til at modtage de værdier, der er indtastet på loginskærmen.
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; } = "";
}
}
Oprettelse af en AccountController
Opret de controllere og handlinger, der kræves for at oprette loginskærmen.
Opret controllernavnet AccountController
som .
Dette skyldes, at controllernavnet og handlingsnavnet på loginskærmen som standard er indstillet til "~/Konto/Login".
Hvis du vil ændre denne sti, kan du gøre det i indstillingerne AddCookie
for metoden i Program.cs.
Indtil videre fortsætter vi med standardindstillingerne.
Lad os først oprette controllersiden.
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
Ved at tildele attributten kan alle handlinger i den udføres uden at blive godkendt.
Dette giver dig kun adgang til loginskærmen uden godkendelse.
AllowAnonymous
Attributter kan også bruges i controllere, der kun indeholder API, og som ikke er relateret til cookiegodkendelse andre steder end på loginskærmen.
Definer derefter de brugere og adgangskoder, der kan logge ind. Oprindeligt ville det blive gemt i en database osv., Men da brugervurdering ikke er hovedfokus denne gang, vil jeg gøre det som et midlertidigt sted.
[AllowAnonymous]
public class AccountController : Controller
{
<summary>仮のユーザーデータベースとする。</summary>
private Dictionary<string, string> UserAccounts { get; set; } = new Dictionary<string, string>
{
{ "user1", "password1" },
{ "user2", "password2" },
};
}
Følgende er en handling, der viser loginskærmen. Da den kun vises, returnerer den visningen, som den er.
<summary>ログイン画面を表示します。</summary>
public IActionResult Login() => View();
Nedenfor er koden, der skal behandles, når du logger ind.
<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");
}
Dette er godkendelsesprocessen efter at have trykket på login-knappen. Hvis brugernavnet og adgangskoden stemmer overens, er godkendelse mulig.
Den beskrevne kode er den minimumskode, der kræves til godkendelse,Claim
ClaimsIdentity
ClaimsPrincipal
og
HttpContext.SignInAsync
Ved at kalde metoden genereres og godkendes en cookie.
Hvis der kræves yderligere krav, eller cookieudløb er påkrævet, tilføjes yderligere parametre.
Når du er logget ind, omdirigeres du til , hvor ~/Home/Index
godkendelse er påkrævet.
Endelig tilføjes logout-processen.
<summary>ログアウト処理を実行します。</summary>
public async Task<IActionResult> Logout()
{
// 認証クッキーをレスポンスから削除
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// ログイン画面にリダイレクト
return RedirectToAction(nameof(Login));
}
HttpContext.SignOutAsync
Ved at kalde metoden kan du slette cookien og returnere den til en tilstand, hvor du ikke er logget ind.
Opret en visning (loginformular) (/Visninger/Konto/Login.cshtml)
Login
Højreklik på handlingen for at tilføje en visning. Du kan også oprette det ved at kopiere det fra en anden fil.
Vi tager ikke hensyn til udseendet. Tilføj felter til indtastning af dit brugernavn og din adgangskode som vist nedenfor, og placer en knap for at logge ind.
Du skal også have et link til adgang uden at logge ind til Home/Index
test.
Da det er besværligt at indtaste brugernavn og adgangskode, indstilles startværdien.
@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"); }
}
Opret et logout-link (/Views/Shared/_Layout.cshtml)
Vi foretager ingen ændringer på startskærmen, men vi sætter et logout-link i navigationslinjen. Til test skal du også sende et link, der fører dig til loginskærmen uden at logge ud.
<!-- 中略 -->
<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>
<!-- 中略 -->
Det er det for MVC-koden.
Bekræftelse af operationen
Dette fuldender den krævede implementering af cookiegodkendelse som minimum. Prøv at køre det og se, hvordan det fungerer. Adfærden bør ændre sig afhængigt af, om du er logget ind eller ej. Som et simpelt eksempel kan du se følgende adfærd.
Operation | ⇒ | driftsresultat |
---|---|---|
Gå hjem uden at logge ind | ⇒ | Omdiriger til login-skærmen |
Login | ⇒ | Gå til startskærmen |
Log ud af hjemmet og gå hjem uden at logge ind | ⇒ | Omdiriger til login-skærmen |
Gå hjem uden at logge ud af hjemmet og logge ind | ⇒ | Gå til startskærmen |