Hozzon létre egy bejelentkezési mechanizmust cookie-hitelesítéssel, és hozzon létre egy mechanizmust, amely átirányítja, ha nincs hitelesítve

Oldal frissítve :
Oldal létrehozásának dátuma :

Működési környezet

Visual Studio
  • Visual Studio Community 2022
ASP.NET Core (MVC, Razor Pages)
6.0

Először

Ezúttal a ASP.NET Core cookie-hitelesítést használ bejelentkezési hitelesítési mechanizmusként. A cookie-hitelesítés hasonló a hagyományos űrlapos hitelesítéshez.

A ASP.NET Core másik hitelesítési mechanizmusa a ASP.NET Core Identity. Az űrlapokkal történő hitelesítés mellett ez lehetővé teszi az API-kkal való hitelesítést, külső bejelentkezési szolgáltatások használatát, jelszavak kezelését és visszaállítását stb. Sok funkciót használhat. Azonban abból a szempontból, hogy ezúttal csak egy egyszerű bejelentkezési képernyőt hoz létre, ez egy kissé túlzott hitelesítési mechanizmus lesz. Ezúttal nem fogjuk használni.

Az ezúttal bemutatott cookie-hitelesítési tippekben a bejelentkezési képernyőn kívül csak akkor jeleníthet meg mást, ha bejelentkezik. Ha megpróbál navigálni egy másik képernyőre, a rendszer átirányítja a bejelentkezési képernyőre. Ha bejelentkezik, megtekintheti a többi képernyőt.

Egyelőre úgy jelentkezhet be, hogy megadja felhasználónevét és jelszavát a bejelentkezési képernyőn. Maga a felhasználói hitelesítés ideiglenes helyként van megvalósítva. Ebben az esetben a fő hangsúly a cookie-hitelesítés megvalósításán van, így a meghatározási folyamat lényege, például a jelszó helyessége nem a lényeg.

Ez a tipp a programnak csak egy részét ismerteti. A teljes kódhoz töltse le a teljes programot. Ez magában foglalja mind az MVC, mind a Razor Pages keretrendszereket.

Projekt létrehozása

Indítsa Visual Studio, és hozzon létre egy új projektet.

A Razor Pages esetében válassza a ASP.NET Core Web App lehetőséget, vagy az MVC esetében válassza a ASP.NET Core Web App (Model-View-Controller) lehetőséget.

Adja meg a választott projektnevet és a projekt helyét.

A hitelesítés típusaként válassza a "Nincs" lehetőséget. Ha más hitelesítést választ, ASP.NET alapvető identitást fogja használni. Ha végzett a beállításokkal, kattintson a "Létrehozás" gombra.

A projekt létrehozása után az alábbi képernyő jelenik meg a hibakeresés végrehajtásakor. Létrehozunk egy programot ezen a képernyőn alapul.

Program szerkesztése.cs (Razor Pages, MVC Common)

Adja hozzá a cookie-hitelesítéshez szükséges definíciókat a Program.cs mezőhöz. A hozzáadandó névterek a következők:

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

Itt látható builder.Services a kód, amelyet hozzá kell adni a .

// === 省略 ===

// 「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();

// === 省略 ===

AddAuthenticationAddCookie A cookie-hitelesítést a és metódus végrehajtásával engedélyezheti. Ha nem kell módosítania a séma nevét, CookieAuthenticationDefaults.AuthenticationScheme adja meg a értéket.

AddAuthorizationoptions.FallbackPolicy RequireAuthenticatedUser Ha megadja a metódust A hitelesítéshez szükséges házirendet minden lapra, vezérlőre és műveletre alkalmazhatja. Ha a bejelentkezési képernyőn kívül bármi máshoz szeretne hitelesítést kérni, ez hasznos módszer a kód csökkentése és a leírás hibáinak megelőzése szempontjából. Külön kell írnia olyan kódot, amely nem igényel hitelesítést a bejelentkezési képernyőhöz.

A kódja a következő app : .

// === 省略 ===

app.UseRouting();

app.UseAuthentication(); // [追加] 認証
app.UseAuthorization(); // 認可

// 「Razor Pages」のコード
// app.MapRazorPages();
// 「MVC」のコード
// app.MapControllerRoute(
//     name: "default",
//     pattern: "{controller=Home}/{action=Index}/{id?}");

// === 省略 ===

Mivel hitelesítési funkciót szeretnénk hozzáadni az alkalmazáshoz, app.UseAuthentication() hozzáadjuk . A leírás helye az MSDN dokumentációjának és alkalmazásának megfelelően található. UseAuthorization(). Ettől eltekintve ez még mindig sablon.

Programok Razor Pages projektekhez

Hozzon létre egy bejelentkezési oldalt (Pages/Account/Login.cshtml.cs)

Fájl létrehozása

Hozzon létre egy bejelentkezési oldalt. A fájl elérési útját a következőképpen kell létrehozni: "/Pages/Account/Login.cshtml". Ez azért van, mert az alapértelmezett bejelentkezési útvonal ilyen. Ha módosítani szeretné ezt az elérési utat, Program.cs ezt a AddCookie metódus argumentumának beállításával teheti meg.

Létrehozhatja más fájlok másolásával ahelyett, hogy a menüből hozná létre, de ebben az esetben kérjük, javítsa ki helyesen a programot.

A bejelentkezési oldal elérésének engedélyezése a felhasználók számára bejelentkezés nélkül

Program.cs Mivel minden oldal csak akkor érhető el, ha be van jelentkezve, csak a bejelentkezési oldalt kell beállítania, hogy akkor is elérhesse, ha nincs bejelentkezve.

AllowAnonymous Attribútumok hozzáadásával a céloldal akkor is elérhető, ha nincs hitelesítve. AllowAnonymous Az attribútumok a bejelentkezési képernyőn kívül más helyeken is használhatók, például a cookie-hitelesítéshez nem kapcsolódó API-műveletekben.

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
  {
  }
}

Változó létrehozása bemenet fogadásához

Amikor bejelentkezik, megadja felhasználónevét, hogy megkaphatja ezeket az értékeket, mert megadja jelszavát.

// 省略

[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; } = "";
}

Felhasználónév és jelszó megadása a bejelentkezési hitelesítéshez

Eredetileg adatbázisban stb. tárolták volna, de mivel ezúttal nem a felhasználói megítélés a fő hangsúly, ideiglenes helyként fogom használni.

// 省略

[AllowAnonymous]
public class LoginModel : PageModel
{
  // 省略

  /// <summary>仮のユーザーデータベースとする。</summary>
  private Dictionary<string, string> UserAccounts { get; set; } = new Dictionary<string, string>
    {
      { "user1", "password1" },
      { "user2", "password2" },
    };
}

Bejelentkezési folyamat

/// <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");
}

Ez a hitelesítési folyamat a bejelentkezési gomb megnyomása után. Ha a felhasználónév és a jelszó megegyezik, a hitelesítés lehetséges.

A leírt kód a hitelesítéshez minimálisan szükséges kód,ClaimClaimsIdentityClaimsPrincipal és HttpContext.SignInAsync A metódus meghívásával cookie jön létre és hitelesítődik.

Ha további jogcímekre van szükség, vagy a cookie lejáratára van szükség, további paraméterek kerülnek hozzáadásra.

A bejelentkezés után a rendszer átirányítja a oldalra, ahol /Index hitelesítésre van szükség.

Kijelentkezési folyamat

/// <summary>ログアウト処理。</summary>
public async Task OnGetLogout()
{
  // 認証クッキーをレスポンスから削除
  await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}

Logout Ha kezelővel fér hozzá, a rendszer feldolgozza a kijelentkezéshez. HttpContext.SignOutAsync A metódus meghívásával törölheti a cookie-t, és visszaállíthatja olyan állapotba, ahol nincs bejelentkezve.

Nézet létrehozása

Nem vesszük figyelembe a megjelenést. Adjon hozzá mezőket a felhasználónév és jelszó megadásához az alábbiak szerint, és helyezzen el egy gombot a bejelentkezéshez. Rendelkeznie kell egy linkkel is, amellyel tesztelés nélkül /Index is hozzáférhet.

Mivel a felhasználónév és a jelszó megadása nehézkes, a kezdeti érték be van állítva.

@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"); }
}

Kijelentkezési hivatkozás létrehozása (/Pages/Shared/_Layout.cshtml)

A kezdőképernyőn nem hajtunk végre módosításokat, de a navigációs sávon elhelyezünk egy kijelentkezési hivatkozást. Ezenkívül teszteléshez tegyen közzé egy linket, amely kijelentkezés nélkül a bejelentkezési képernyőre viszi.

<!-- 中略 -->
<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>
<!-- 中略 -->

Ennyit a Razor Pages kódról.

MVC projektek programjai

Bejelentkezési modell létrehozása

Létrehozott egy modellt a bejelentkezési képernyőn megadott értékek fogadásához.

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; } = "";
  }
}

AccountController létrehozása

Hozza létre a bejelentkezési képernyő létrehozásához szükséges vezérlőket és műveleteket. Hozza létre a vezérlő nevét AccountController . Ez azért van, mert alapértelmezés szerint a vezérlő neve és a művelet neve a bejelentkezési képernyőn "~/Account/Login" értékre van állítva. Ha módosítani szeretné ezt az elérési utat, ezt megteheti a Program.cs metódus beállításaiban AddCookie . Egyelőre folytatjuk az alapértelmezett beállításokat.

Először hozzuk létre a vezérlő oldalt.

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 Az attribútum megadásával az összes benne lévő művelet hitelesítés nélkül végrehajtható. Ez lehetővé teszi, hogy hitelesítés nélkül csak a bejelentkezési képernyőt érje el.

AllowAnonymous Az attribútumok olyan csak API-vezérlőkben is használhatók, amelyek nem kapcsolódnak a cookie-hitelesítéshez a bejelentkezési képernyőn kívül.

Ezután határozza meg a bejelentkezéshez szükséges felhasználókat és jelszavakat. Eredetileg adatbázisban stb. tárolták volna, de mivel ezúttal nem a felhasználói megítélés a fő hangsúly, ideiglenes helyként fogom használni.

[AllowAnonymous]
public class AccountController : Controller
{
  /// <summary>仮のユーザーデータベースとする。</summary>
  private Dictionary<string, string> UserAccounts { get; set; } = new Dictionary<string, string>
    {
      { "user1", "password1" },
      { "user2", "password2" },
    };
}

A következő művelet megjeleníti a bejelentkezési képernyőt. Mivel csak megjelenik, a nézetet változatlanul adja vissza.

/// <summary>ログイン画面を表示します。</summary>
public IActionResult Login() => View();

Az alábbiakban látható a bejelentkezéskor feldolgozandó kód.

/// <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");
}

Ez a hitelesítési folyamat a bejelentkezési gomb megnyomása után. Ha a felhasználónév és a jelszó megegyezik, a hitelesítés lehetséges.

A leírt kód a hitelesítéshez minimálisan szükséges kód,ClaimClaimsIdentityClaimsPrincipal és HttpContext.SignInAsync A metódus meghívásával cookie jön létre és hitelesítődik.

Ha további jogcímekre van szükség, vagy a cookie lejáratára van szükség, további paraméterek kerülnek hozzáadásra.

A bejelentkezés után a rendszer átirányítja a oldalra, ahol ~/Home/Index hitelesítésre van szükség.

Végül hozzáadódik a kijelentkezési folyamat.

/// <summary>ログアウト処理を実行します。</summary>
public async Task<IActionResult> Logout()
{
  // 認証クッキーをレスポンスから削除
  await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

  // ログイン画面にリダイレクト
  return RedirectToAction(nameof(Login));
}

HttpContext.SignOutAsync A metódus meghívásával törölheti a cookie-t, és visszaállíthatja olyan állapotba, ahol nincs bejelentkezve.

Nézet létrehozása (bejelentkezési űrlap) (/Views/Account/Login.cshtml)

Login Kattintson a jobb gombbal a műveletre nézet hozzáadásához. Létrehozhatja egy másik fájlból történő másolással is.

Nem vesszük figyelembe a megjelenést. Adjon hozzá mezőket a felhasználónév és jelszó megadásához az alábbiak szerint, és helyezzen el egy gombot a bejelentkezéshez. Rendelkeznie kell egy linkkel is, amellyel tesztelés nélkül Home/Index is hozzáférhet.

Mivel a felhasználónév és a jelszó megadása nehézkes, a kezdeti érték be van állítva.

@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"); }
}

Kijelentkezési hivatkozás létrehozása (/Views/Shared/_Layout.cshtml)

A kezdőképernyőn nem hajtunk végre módosításokat, de a navigációs sávon elhelyezünk egy kijelentkezési hivatkozást. Ezenkívül teszteléshez tegyen közzé egy linket, amely kijelentkezés nélkül a bejelentkezési képernyőre viszi.

<!-- 中略 -->
<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>
<!-- 中略 -->

Ennyi az MVC kódhoz.

A működés megerősítése

Ezzel befejeződik a cookie-hitelesítés minimálisan szükséges megvalósítása. Próbálja meg futtatni, és nézze meg, hogyan működik. A viselkedésnek attól függően kell változnia, hogy be van-e jelentkezve vagy sem. Egyszerű példaként a következő viselkedést láthatja.

Művelet művelet eredménye
Menj haza bejelentkezés nélkül Átirányítás a bejelentkezési képernyőre
bejelentkezés Ugrás a kezdőképernyőre
Jelentkezzen ki otthonról, és menjen haza bejelentkezés nélkül Átirányítás a bejelentkezési képernyőre
Menjen haza anélkül, hogy kijelentkezne otthonából és bejelentkezne Ugrás a kezdőképernyőre