Looge küpsiste autentimise abil sisselogimismehhanism ja looge mehhanism, mis suunatakse ümber, kui te pole autenditud

Lehekülg uuendatud :
Lehe loomise kuupäev :

Töökeskkond

Visuaalne stuudio
  • Visual Studio kogukond 2022
ASP.NET Core (MVC, habemenuga lehed)
6.0

Alguses

Seekord kasutab ASP.NET Core sisselogimise autentimismehhanismina küpsiste autentimist. Võite mõelda küpsistega autentimisele kui sarnasele traditsioonilisele autentimisvormile.

Teine ASP.NET Core'i autentimismehhanism on ASP.NET Core Identity. Lisaks vormide abil autentimisele võimaldab see autentida API-dega, kasutada väliseid sisselogimisteenuseid, hallata ja lähtestada paroole jne. Võite kasutada palju funktsioone. Kuid seekord lihtsa sisselogimisekraani loomise seisukohast on see mõnevõrra liialdatud autentimismehhanism. Me ei kasuta seda seekord.

Seekord tutvustatud küpsiste autentimise näpunäidetes ei saa te kuvada midagi muud kui sisselogimisekraani, kui te sisse ei logi. Kui proovite navigeerida teisele ekraanile, suunatakse teid sisselogimisekraanile. Kui logite sisse, saate vaadata teisi ekraane.

Praegu saate sisse logida, sisestades sisselogimisekraanile oma kasutajanime ja parooli. Kasutaja autentimine ise rakendatakse ajutise kohana. Sellisel juhul on põhirõhk küpsiste autentimise rakendamisel, seega ei ole määramisprotsessi olemus, näiteks see, kas parool on õige, oluline.

See näpunäide kirjeldab ainult osa programmist. Täieliku koodi saamiseks laadige alla kogu programm. See hõlmab ka nii MVC kui ka Razor Pages raamistikke.

Projekti loomine

Käivitage Visual Studio ja looge uus projekt.

Razor Pagesi jaoks valige ASP.NET Core Web App või MVC jaoks valige ASP.NET Core Web App (Model-View-Controller).

Määrake valitud projekti nimi ja projekti asukoht.

Autentimise tüübiks valige "Puudub". Kui valite muu autentimise, kasutate ASP.NET Core Identity. Kui olete seadetega lõpetanud, klõpsake nuppu "Loo".

Pärast projekti loomist kuvatakse silumise käivitamisel allpool näidatud ekraan. Loome selle ekraani põhjal programmi.

Redigeerimisprogramm.cs (habemenuga lehed, MVC tavaline)

Lisage küpsise autentimiseks vajalikud definitsioonid programmi Program.cs. Lisatavad nimeruumid on järgmised:

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

Siin on builder.Services kood, mille soovite lisada.

// === 省略 ===

// 「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 Küpsiste autentimise saate lubada, käivitades meetodi. Kui te ei pea skeemi nime muutma, CookieAuthenticationDefaults.AuthenticationScheme määrake .

AddAuthorization Kui määrate options.FallbackPolicy RequireAuthenticatedUser meetodi jaoks Autentimiseks vajalikku poliitikat saate rakendada kõigile lehtedele, kõigile kontrolleritele ja toimingutele. Kui soovite nõuda autentimist millegi muu kui sisselogimisekraani jaoks, on see kasulik meetod koodi vähendamiseks ja kirjelduses esinevate vigade vältimiseks. Peate kirjutama koodi, mis ei nõua sisselogimisekraanil eraldi autentimist.

Järgmine on app kood .

// === 省略 ===

app.UseRouting();

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

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

// === 省略 ===

Kuna soovime rakendusele lisada autentimisfunktsiooni, app.UseAuthentication() lisame . Kirjelduse asukoht on vastavalt MSDN-i dokumentatsioonile, rakendusele. UseAuthorization(). Peale selle on see ikkagi mall.

Razor Pages'i projektide programmid

Looge sisselogimisleht (Pages/Account/Login.cshtml.cs)

Faili loomine

Looge sisselogimisleht. Failitee tuleks luua kujul "/Pages/Account/Login.cshtml". Seda seetõttu, et vaikimisi sisselogimistee on selline. Kui soovite seda teed muuta, saate Program.cs seda teha, seades argumendiks AddCookie meetodi .

Saate selle luua, kopeerides menüüst loomise asemel teisi faile, kuid sel juhul parandage programm õigesti.

Luba kasutajatel sisselogimislehele juurde pääseda ilma sisse logimata

Program.cs Kuna kõigile lehtedele pääseb juurde ainult siis, kui olete sisse logitud, peate määrama ainult sisselogimislehe, et pääseksite sellele juurde ka siis, kui te pole sisse logitud.

AllowAnonymous Atribuutide lisamisega pääseb sihtlehele juurde ka siis, kui see pole autenditud. AllowAnonymous Atribuute võib kasutada ka muudes kohtades peale sisselogimiskuva, näiteks API toimingutes, mis ei ole seotud küpsiste autentimisega.

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

Muutuja loomine sisendi vastuvõtmiseks

Sisselogimisel deklareerite oma kasutajanime, et saaksite need väärtused vastu võtta, kuna sisestate oma parooli.

// 省略

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

Määrake sisselogimise autentimiseks kasutajanimi ja parool

Algselt salvestataks see andmebaasi jne, kuid kuna kasutaja hinnang ei ole seekord põhirõhk, teen selle ajutise kohana.

// 省略

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

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

Logi sisse

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

See on autentimisprotsess pärast sisselogimisnupu vajutamist. Kui kasutajanimi ja parool ühtivad, on autentimine võimalik.

Kirjeldatud kood on autentimiseksClaimClaimsIdentityClaimsPrincipal vajalik miinimumkood ja HttpContext.SignInAsync Meetodile helistades genereeritakse ja autenditakse küpsis.

Kui on vaja täiendavaid nõudeid või kui on vaja küpsiste aegumist, lisatakse täiendavad parameetrid.

Pärast sisselogimist suunatakse teid jaotisse , kus /Index on nõutav autentimine.

Väljalogimise protsess

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

Logout Kui kasutate käitlejat, töödeldakse seda väljalogimiseks. HttpContext.SignOutAsync Meetodile helistades saate küpsise kustutada ja tagastada selle olekusse, kus te pole sisse logitud.

Vaate loomine

Me ei võta välimust arvesse. Lisage väljad oma kasutajanime ja parooli sisestamiseks, nagu allpool näidatud, ja asetage sisselogimiseks nupp. Teil peaks olema ka link juurdepääsuks ilma testimiseks /Index sisse logimata.

Kuna kasutajanime ja parooli sisestamine on tülikas, määratakse algväärtus.

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

Väljalogimislingi loomine (/Pages/Shared/_Layout.cshtml)

Me ei tee avakuval muudatusi, kuid paneme navigeerimisribale väljalogimislingi. Samuti postitage testimiseks link, mis viib teid sisselogimisekraanile ilma välja logimata.

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

See ongi Razor Pages koodi jaoks.

MVC projektide programmid

Sisselogimismudeli loomine

Olete loonud mudeli sisselogimisekraanile sisestatud väärtuste vastuvõtmiseks.

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

AccountControlleri loomine

Looge sisselogimisekraani loomiseks vajalikud kontrollerid ja toimingud. Looge kontrolleri nimi AccountController kujul . Seda seetõttu, et vaikimisi on kontrolleri nimi ja toimingu nimi sisselogimisekraanil seatud väärtusele "~/Account/Login". Kui soovite seda teed muuta, saate seda teha meetodi suvandites AddCookie programmis .cs. Praegu jätkame vaikesätetega.

Esiteks loome kontrolleri poole.

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 Atribuudi andmisega saab kõiki selles sisalduvaid toiminguid teha ilma autentimata. See võimaldab teil ilma autentimiseta juurde pääseda ainult sisselogimisekraanile.

AllowAnonymous Atribuute võidakse kasutada ka ainult API-ga kaitstud kontrollerites, mis ei ole seotud küpsiste autentimisega mujal kui sisselogimiskuval.

Seejärel määratlege kasutajad ja paroolid, kes saavad sisse logida. Algselt salvestataks see andmebaasi jne, kuid kuna kasutaja hinnang ei ole seekord põhirõhk, teen selle ajutise kohana.

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

Järgmine on toiming, mis kuvab sisselogimisekraani. Kuna see kuvatakse ainult, tagastab see vaate sellisena, nagu see on.

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

Allpool on kood, mida tuleb sisselogimisel töödelda.

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

See on autentimisprotsess pärast sisselogimisnupu vajutamist. Kui kasutajanimi ja parool ühtivad, on autentimine võimalik.

Kirjeldatud kood on autentimiseksClaimClaimsIdentityClaimsPrincipal vajalik miinimumkood ja HttpContext.SignInAsync Meetodile helistades genereeritakse ja autenditakse küpsis.

Kui on vaja täiendavaid nõudeid või kui on vaja küpsiste aegumist, lisatakse täiendavad parameetrid.

Pärast sisselogimist suunatakse teid jaotisse , kus ~/Home/Index on nõutav autentimine.

Lõpuks lisatakse väljalogimisprotsess.

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

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

HttpContext.SignOutAsync Meetodile helistades saate küpsise kustutada ja tagastada selle olekusse, kus te pole sisse logitud.

Vaate loomine (sisselogimisvorm) (/Views/Account/Login.cshtml)

Login Vaate lisamiseks paremklõpsake toimingut. Samuti saate selle luua, kopeerides selle teisest failist.

Me ei võta välimust arvesse. Lisage väljad oma kasutajanime ja parooli sisestamiseks, nagu allpool näidatud, ja asetage sisselogimiseks nupp. Teil peaks olema ka link juurdepääsuks ilma testimiseks Home/Index sisse logimata.

Kuna kasutajanime ja parooli sisestamine on tülikas, määratakse algväärtus.

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

Väljalogimislingi loomine (/Views/Shared/_Layout.cshtml)

Me ei tee avakuval muudatusi, kuid paneme navigeerimisribale väljalogimislingi. Samuti postitage testimiseks link, mis viib teid sisselogimisekraanile ilma välja logimata.

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

See ongi MVC-koodi jaoks.

Toimingu kinnitamine

See lõpetab küpsiste autentimise minimaalse nõutava rakendamise. Proovige seda käivitada ja vaadake, kuidas see töötab. Käitumine peaks muutuma sõltuvalt sellest, kas olete sisse logitud või mitte. Lihtsa näitena näete järgmist käitumist.

Toimingu tulemus
Mine koju ilma sisse logimata Ümbersuunamine sisselogimiskuvale
Login Avakuvale liikumine
Logige kodust välja ja minge koju ilma sisse logimata Ümbersuunamine sisselogimiskuvale
Mine koju ilma kodust välja logimata ja sisse logimata Avakuvale liikumine