Luo kirjautumismekanismi evästetodennuksen avulla ja luo mekanismi, joka ohjataan uudelleen, jos sinua ei ole todennettu

Sivu päivitetty :
Sivun luontipäivämäärä :

Toimintaympäristö

Visuaalinen studio
  • Visual Studio -yhteisö 2022
ASP.NET Core (MVC, partakoneen sivut)
6.0

Alun perin

Tällä kertaa ASP.NET Core käyttää evästetodennusta kirjautumisen todennusmekanismina. Voit ajatella, että evästetodennus on samanlainen kuin perinteinen lomaketodennus.

Toinen ASP.NET Coren todennusmekanismi on ASP.NET Core Identity. Lomakkeilla tapahtuvan todennuksen lisäksi voit todentaa sovellusliittymillä, käyttää ulkoisia kirjautumispalveluita, hallita ja nollata salasanoja jne. Voit käyttää monia ominaisuuksia. Kuitenkin vain yksinkertaisen kirjautumisnäytön luomisen näkökulmasta tällä kertaa se on hieman liioiteltu todennusmekanismi. Emme käytä sitä tällä kertaa.

Tällä kertaa esitellyissä evästeiden todennusvinkeissä et voi näyttää muuta kuin kirjautumisnäytön, ellet kirjaudu sisään. Jos yrität siirtyä toiseen näyttöön, sinut ohjataan kirjautumisnäyttöön. Jos kirjaudut sisään, voit tarkastella muita näyttöjä.

Toistaiseksi voit kirjautua sisään syöttämällä käyttäjätunnuksesi ja salasanasi kirjautumisnäyttöön. Itse käyttäjän todennus toteutetaan väliaikaisena paikkana. Tässä tapauksessa pääpaino on evästetodennuksen toteuttamisessa, joten määritysprosessin ydin, kuten salasanan oikeellisuus, ei ole ydin.

Tämä vinkki kuvaa vain osan ohjelmasta. Saat koko koodin lataamalla koko ohjelman. Se kattaa myös sekä MVC- että Razor Pages -kehykset.

Luo projekti

Käynnistä Visual Studio ja luo uusi projekti.

Valitse Razor Pages -kohdassa ASP.NET Core Web App tai MVC-kohdassa ASP.NET Core Web App (Model-View-Controller).

Määritä haluamasi projektin nimi ja projektin sijainti.

Valitse todennustyypiksi "Ei mitään". Jos valitset muun todennuksen, käytät ASP.NET ydinidentiteettiä. Kun olet tehnyt asetukset, napsauta "Luo" -painiketta.

Kun olet luonut projektin, alla oleva näyttö tulee näkyviin, kun virheenkorjaus suoritetaan. Luomme ohjelman tämän näytön perusteella.

Muokkaa ohjelmaa.cs (partakoneen sivut, MVC yleinen)

Lisää evästetodennukseen tarvittavat määritykset kohtaan Ohjelma.cs. Lisättävät nimiavaruudet ovat seuraavat:

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

Tässä on builder.Services koodi, johon voit lisätä .

// === 省略 ===

// 「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 Voit ottaa evästetodennuksen käyttöön suorittamalla ja-menetelmän. Jos mallin nimeä ei tarvitse muuttaa, CookieAuthenticationDefaults.AuthenticationScheme määritä .

AddAuthorization Jos määrität options.FallbackPolicy RequireAuthenticatedUser menetelmälle Voit käyttää todennusta vaativaa käytäntöä kaikilla sivuilla, kaikilla ohjauskoneilla ja toiminnoissa. Jos haluat vaatia todennusta muulle kuin kirjautumisnäytölle, se on hyödyllinen tapa vähentää koodia ja estää virheitä kuvauksessa. Sinun on kirjoitettava koodi, joka ei vaadi kirjautumisnäytön todennusta erikseen.

Seuraavassa on app .

// === 省略 ===

app.UseRouting();

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

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

// === 省略 ===

Koska haluamme lisätä todennustoiminnon sovellukseen, app.UseAuthentication() lisäämme . Kuvauksen sijainti on MSDN:n dokumentaation, sovelluksen mukainen. UseAuthorization(). Muuten se on edelleen malli.

Razor Pages -projektien ohjelmat

Luo kirjautumissivu (Pages/Account/Login.cshtml.cs)

Luo tiedosto

Luo kirjautumissivu. Tiedostopolku tulee luoda muodossa "/Pages/Account/Login.cshtml". Tämä johtuu siitä, että oletuskirjautumispolku on tällainen. Jos haluat muuttaa tätä polkua, voit Program.cs tehdä sen määrittämällä AddCookie .

Voit luoda sen kopioimalla muita tiedostoja sen sijaan, että luot sen valikosta, mutta korjaa siinä tapauksessa ohjelma oikein.

Salli käyttäjien käyttää kirjautumissivua kirjautumatta sisään

Program.cs Koska kaikille sivuille pääsee vain, kun olet kirjautunut sisään, sinun on asetettava vain kirjautumissivu, jotta voit käyttää sitä, vaikka et olisi kirjautunut sisään.

AllowAnonymous Kun määritteitä lisätään, kohdesivua voidaan käyttää, vaikka sitä ei olisi todennettu. AllowAnonymous Attribuutteja voidaan käyttää muualla kuin kirjautumisnäytössä, kuten API-toiminnoissa, jotka eivät liity evästeiden todentamiseen.

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

Luo muuttuja syötteen vastaanottamista varten

Kun kirjaudut sisään, ilmoitat käyttäjänimesi, jotta voit vastaanottaa nämä arvot, koska annat salasanasi.

// 省略

[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ääritä käyttäjätunnus ja salasana kirjautumistodennusta varten

Alun perin se tallennettiin tietokantaan jne., Mutta koska käyttäjän arviointi ei ole tällä kertaa pääpaino, teen siitä väliaikaisen paikan.

// 省略

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

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

Kirjautumisprosessi

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

Tämä on todennusprosessi kirjautumispainikkeen painamisen jälkeen. Jos käyttäjänimi ja salasana täsmäävät, todennus on mahdollista.

Kuvattu koodi on todentamiseen vaadittava vähimmäiskoodi,ClaimClaimsIdentityClaimsPrincipal ja HttpContext.SignInAsync Kutsumalla menetelmää eväste luodaan ja todennetaan.

Jos tarvitaan lisävaatimuksia tai evästeen vanhentumista, lisäparametreja lisätään.

Kun olet kirjautunut sisään, sinut ohjataan , jossa /Index todennus vaaditaan.

Kirjaudu ulos

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

Logout Kun sitä käytetään käsittelijällä, se käsitellään uloskirjautumista varten. HttpContext.SignOutAsync Kutsumalla menetelmää voit poistaa evästeen ja palauttaa sen tilaan, jossa et ole kirjautunut sisään.

Näkymän luominen

Emme ota huomioon ulkonäköä. Lisää kentät käyttäjätunnuksen ja salasanan syöttämistä varten alla olevan kuvan mukaisesti ja aseta painike kirjautuaksesi sisään. Sinulla pitäisi myös olla linkki pääsyyn kirjautumatta sisään testausta varten /Index .

Koska käyttäjänimen ja salasanan syöttäminen on hankalaa, alkuarvo asetetaan.

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

Luo uloskirjautumislinkki (/Pages/Shared/_Layout.cshtml)

Emme tee muutoksia aloitusnäyttöön, mutta lisäämme uloskirjautumislinkin navigointipalkkiin. Lähetä testausta varten myös linkki, joka vie sinut kirjautumisnäyttöön kirjautumatta ulos.

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

Siinä se Razor Pages -koodille.

MVC-projektien ohjelmat

Kirjautumismallin luominen

Olet luonut mallin, joka vastaanottaa kirjautumisnäyttöön syötetyt arvot.

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

AccountControllerin luominen

Luo kirjautumisnäytön luomiseen tarvittavat ohjaimet ja toiminnot. Luo tallentimen nimeksi AccountController . Tämä johtuu siitä, että oletusarvoisesti ohjaimen nimi ja toiminnon nimi kirjautumisnäytössä on "~/Account/Login". Jos haluat muuttaa tätä polkua, voit tehdä sen menetelmän vaihtoehdoissa AddCookie kohdassa Ohjelma.cs. Toistaiseksi jatkamme oletusasetuksia.

Luodaan ensin ohjainpuoli.

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 Myöntämällä määritteen kaikki sen toiminnot voidaan suorittaa ilman todennusta. Näin voit käyttää vain kirjautumisnäyttöä ilman todennusta.

AllowAnonymous Attribuutteja voidaan käyttää myös vain API-rekisterinpitäjissä, jotka eivät liity evästeiden todentamiseen muualla kuin kirjautumisnäytössä.

Määritä seuraavaksi käyttäjät ja salasanat, jotka voivat kirjautua sisään. Alun perin se tallennettiin tietokantaan jne., Mutta koska käyttäjän arviointi ei ole tällä kertaa pääpaino, teen siitä väliaikaisen paikan.

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

Seuraavassa on toiminto, joka näyttää kirjautumisnäytön. Koska se näytetään vain, se palauttaa näkymän sellaisenaan.

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

Alla on koodi, joka käsitellään kirjautumisen yhteydessä.

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

Tämä on todennusprosessi kirjautumispainikkeen painamisen jälkeen. Jos käyttäjänimi ja salasana täsmäävät, todennus on mahdollista.

Kuvattu koodi on todentamiseen vaadittava vähimmäiskoodi,ClaimClaimsIdentityClaimsPrincipal ja HttpContext.SignInAsync Kutsumalla menetelmää eväste luodaan ja todennetaan.

Jos tarvitaan lisävaatimuksia tai evästeen vanhentumista, lisäparametreja lisätään.

Kun olet kirjautunut sisään, sinut ohjataan , jossa ~/Home/Index todennus vaaditaan.

Lopuksi uloskirjautumisprosessi lisätään.

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

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

HttpContext.SignOutAsync Kutsumalla menetelmää voit poistaa evästeen ja palauttaa sen tilaan, jossa et ole kirjautunut sisään.

Luo näkymä (kirjautumislomake) (/Views/Account/Login.cshtml)

Login Napsauta toimintoa hiiren kakkospainikkeella lisätäksesi näkymän. Voit luoda sen myös kopioimalla sen toisesta tiedostosta.

Emme ota huomioon ulkonäköä. Lisää kentät käyttäjätunnuksen ja salasanan syöttämistä varten alla olevan kuvan mukaisesti ja aseta painike kirjautuaksesi sisään. Sinulla pitäisi myös olla linkki pääsyyn kirjautumatta sisään testausta varten Home/Index .

Koska käyttäjänimen ja salasanan syöttäminen on hankalaa, alkuarvo asetetaan.

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

Uloskirjautumislinkin luominen (/Views/Shared/_Layout.cshtml)

Emme tee muutoksia aloitusnäyttöön, mutta lisäämme uloskirjautumislinkin navigointipalkkiin. Lähetä testausta varten myös linkki, joka vie sinut kirjautumisnäyttöön kirjautumatta ulos.

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

Siinä se MVC-koodille.

Toiminnan vahvistaminen

Tämä täyttää evästetodennuksen vähimmäisvaatimukset. Kokeile suorittaa se ja katso, miten se toimii. Toiminnan pitäisi muuttua sen mukaan, oletko kirjautunut sisään vai et. Yksinkertaisena esimerkkinä näet seuraavan toiminnan.

Käyttö- toiminnan tulos
Siirry kotiin kirjautumatta sisään Ohjaa kirjautumisnäyttöön
sisäänkirjautuminen Siirry aloitusnäyttöön
Kirjaudu ulos kotoa ja mene kotiin kirjautumatta sisään Ohjaa kirjautumisnäyttöön
Mene kotiin kirjautumatta ulos kodista ja kirjautumatta sisään Siirry aloitusnäyttöön