Creeu un mecanisme d'inici de sessió mitjançant l'autenticació de galetes i creeu un mecanisme per ser redirigit si no esteu autenticat

Pàgina actualitzada :
Data de creació de la pàgina :

Entorn operatiu

Estudi visual
  • Comunitat Visual Studio 2022
ASP.NET Core (MVC, pàgines d'afaitar)
6.0

Al principi

Aquesta vegada, ASP.NET Core utilitzarà l'autenticació de cookies com a mecanisme d'autenticació d'inici de sessió. Podeu pensar que l'autenticació de galetes és similar a l'autenticació de formularis tradicionals.

Un altre mecanisme d'autenticació per a ASP.NET Core és ASP.NET Core Identity. A més de l'autenticació mitjançant formularis, permet autenticar-se amb API, utilitzar serveis d'inici de sessió externs, gestionar i restablir contrasenyes, etc. Podeu utilitzar moltes funcions. No obstant això, des del punt de vista de només crear una simple pantalla d'inici de sessió aquesta vegada, serà un mecanisme d'autenticació una mica exagerat. Aquesta vegada no l'utilitzarem.

En els consells d'autenticació de cookies introduïts aquesta vegada, no podrà mostrar res més que la pantalla d'inici de sessió tret que iniciï sessió. Si intenteu navegar a una altra pantalla, se us redirigirà a la pantalla d'inici de sessió. Si inicieu sessió, podreu veure altres pantalles.

De moment, pots iniciar sessió introduint el teu nom d'usuari i contrasenya a la pantalla d'inici de sessió. La pròpia autenticació de l'usuari s'implementa com un lloc temporal. En aquest cas, el focus principal està en la implementació de l'autenticació de cookies, de manera que l'essència del procés de determinació, com ara si la contrasenya és correcta, no és l'essència.

Aquest consell descriu només una part del programa. Per obtenir el codi complet, descarregueu el programa complet. També cobreix els marcs MVC i Razor Pages.

Crear un projecte

Inicieu Visual Studio i creeu un projecte nou.

Per a Pàgines d'afaitar, seleccioneu ASP.NET aplicació web principal o per a MVC, seleccioneu ASP.NET aplicació web principal (model-vista-controlador).

Especifiqueu un nom de projecte que trieu i una ubicació per al projecte.

Per al tipus d'autenticació, seleccioneu "Cap". Si trieu una altra autenticació, utilitzareu ASP.NET identitat bàsica. Quan hàgiu acabat amb la configuració, feu clic al botó "Crea".

Després de crear el projecte, es mostrarà la pantalla que es mostra a continuació quan s'executi la depuració. Crearem un programa basat en aquesta pantalla.

Programa d'edició.cs (Pàgines d'afaitar, MVC Common)

Afegiu les definicions necessàries per a l'autenticació de galetes a Programa.cs. Els espais de noms a afegir són els següents:

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

Aquí teniu builder.Services el codi per afegir 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 Podeu habilitar l'autenticació de galetes executant el mètode and. Si no necessiteu canviar el nom de l'esquema, CookieAuthenticationDefaults.AuthenticationScheme especifiqueu .

AddAuthorization Si especifiqueu options.FallbackPolicy RequireAuthenticatedUser el mètode Podeu aplicar una norma necessària per a l'autenticació a totes les pàgines, a tots els controladors i a les accions. Si voleu requerir autenticació per a qualsevol cosa que no sigui la pantalla d'inici de sessió, és un mètode útil per reduir el codi i evitar errors en la descripció. Haureu d'escriure codi que no requereixi autenticació per a la pantalla d'inici de sessió per separat.

El següent és app el codi per a .

// === 省略 ===

app.UseRouting();

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

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

// === 省略 ===

Ja que volem afegir funcionalitat d'autenticació a l'aplicació, app.UseAuthentication() afegirem . La ubicació de la descripció és segons la documentació de l'MSDN, aplicació. Autorització d'ús(). A part d'això, no deixa de ser una plantilla.

Programes per a projectes Razor Pages

Creeu una pàgina d'inici de sessió (Pages/Compte/Login.cshtml.cs)

Crear un fitxer

Creeu una pàgina d'inici de sessió. La ruta del fitxer s'ha de crear com a "/Pages/Compte/Login.cshtml". Això es deu al fet que el camí d'inici de sessió predeterminat és així. Si voleu canviar aquest camí, podeu Program.cs fer-ho establint l'argument del AddCookie mètode de .

Podeu crear-lo copiant altres fitxers en lloc de crear-lo des del menú, però en aquest cas, corregiu el programa correctament.

Permetre als usuaris accedir a la pàgina d'inici de sessió sense iniciar sessió

Program.cs Com que només es pot accedir a totes les pàgines quan heu iniciat la sessió, només heu d'establir la pàgina d'inici de sessió perquè pugueu accedir-hi fins i tot si no heu iniciat la sessió.

AllowAnonymous En afegir atributs, es pot accedir a la pàgina de destinació encara que no estigui autenticada. AllowAnonymous Els atributs es poden utilitzar en altres llocs diferents de la pantalla d'inici de sessió, com ara operacions d'API no relacionades amb l'autenticació de galetes.

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

Crear una variable per rebre l'entrada

Quan inicieu sessió, declareu el vostre nom d'usuari per poder rebre aquests valors perquè introduïu la vostra contrasenya.

// 省略

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

Definir un nom d'usuari i una contrasenya per a l'autenticació d'inici de sessió

Originalment, s'emmagatzemaria en una base de dades, etc., però com que el judici de l'usuari no és el focus principal aquesta vegada, ho faré com un lloc temporal.

// 省略

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

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

Procés d'inici de sessió

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

Aquest és el procés d'autenticació després de prémer el botó d'inici de sessió. Si el nom d'usuari i la contrasenya coincideixen, l'autenticació és possible.

El codi descrit és el codi mínim necessari per a l'autenticació,ClaimClaimsIdentityClaimsPrincipal i HttpContext.SignInAsync Cridant al mètode, es genera i autentica una galeta.

Si es requereixen reclamacions addicionals o es requereix la caducitat de la galeta, s'afegeixen paràmetres addicionals.

Després d'iniciar sessió, se us redirigeix a , on /Index es requereix autenticació.

Procés de tancament de sessió

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

Logout Quan s'accedeix amb un controlador, es processa per tancar la sessió. HttpContext.SignOutAsync Si truqueu al mètode, podeu eliminar la galeta i tornar-la a un estat on no hàgiu iniciat la sessió.

Creació d'una visualització

No tenim en compte l'aspecte. Afegiu camps per introduir el vostre nom d'usuari i contrasenya com es mostra a continuació i col·loqueu un botó per iniciar la sessió. També hauríeu de tenir un enllaç per accedir sense iniciar sessió per fer /Index proves.

Com que és problemàtic introduir el nom d'usuari i la contrasenya, s'estableix el valor inicial.

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

Creeu un enllaç de tancament de sessió (/Pages/Compartit/_Layout.cshtml)

No farem cap canvi a la pantalla d'inici, però posarem un enllaç de tancament de sessió a la barra de navegació. A més, per fer proves, publiqueu un enllaç que us porti a la pantalla d'inici de sessió sense tancar la sessió.

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

Això és tot per al codi Razor Pages.

Programes per a projectes MVC

Creació d'un model d'inici de sessió

Heu creat un model per rebre els valors introduïts a la pantalla d'inici de sessió.

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

Creació d'un controlador de comptes

Creeu els controladors i les accions necessàries per crear la pantalla d'inici de sessió. Creeu el nom AccountController del controlador com a . Això es deu al fet que, per defecte, el nom del controlador i el nom de l'acció a la pantalla d'inici de sessió estan definits com a "~/Compte/Inici de sessió". Si voleu canviar aquesta ruta, podeu fer-ho en les opcions del AddCookie mètode a Programa.cs. De moment, continuarem amb la configuració predeterminada.

En primer lloc, creem el costat del controlador.

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 En concedir l'atribut, totes les accions que hi ha es poden realitzar sense autenticar-se. Això us permet accedir només a la pantalla d'inici de sessió sense autenticació.

AllowAnonymous Els atributs també es poden utilitzar en controladors només de l'API que no estiguin relacionats amb l'autenticació de galetes en altres llocs que no siguin la pantalla d'inici de sessió.

A continuació, definiu els usuaris i les contrasenyes que poden iniciar la sessió. Originalment, s'emmagatzemaria en una base de dades, etc., però com que el judici de l'usuari no és el focus principal aquesta vegada, ho faré com un lloc temporal.

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

A continuació es mostra una acció que mostra la pantalla d'inici de sessió. Com que només es mostra, retorna la vista tal qual.

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

A continuació es mostra el codi que s'ha de processar en iniciar sessió.

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

Aquest és el procés d'autenticació després de prémer el botó d'inici de sessió. Si el nom d'usuari i la contrasenya coincideixen, l'autenticació és possible.

El codi descrit és el codi mínim necessari per a l'autenticació,ClaimClaimsIdentityClaimsPrincipal i HttpContext.SignInAsync Cridant al mètode, es genera i autentica una galeta.

Si es requereixen reclamacions addicionals o es requereix la caducitat de la galeta, s'afegeixen paràmetres addicionals.

Després d'iniciar sessió, se us redirigeix a , on ~/Home/Index es requereix autenticació.

Finalment, s'afegeix el procés de sortida.

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

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

HttpContext.SignOutAsync Si truqueu al mètode, podeu eliminar la galeta i tornar-la a un estat on no hàgiu iniciat la sessió.

Crear una vista (formulari d'inici de sessió) (/Views/Account/Login.cshtml)

Login Feu clic amb el botó dret a l'acció per afegir una visualització. També podeu crear-lo copiant-lo d'un altre fitxer.

No tenim en compte l'aspecte. Afegiu camps per introduir el vostre nom d'usuari i contrasenya com es mostra a continuació i col·loqueu un botó per iniciar la sessió. També hauríeu de tenir un enllaç per accedir sense iniciar sessió per fer Home/Index proves.

Com que és problemàtic introduir el nom d'usuari i la contrasenya, s'estableix el valor inicial.

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

Creeu un enllaç de tancament de sessió (/Views/Shared/_Layout.cshtml)

No farem cap canvi a la pantalla d'inici, però posarem un enllaç de tancament de sessió a la barra de navegació. A més, per fer proves, publiqueu un enllaç que us porti a la pantalla d'inici de sessió sense tancar la sessió.

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

Això és tot per al codi MVC.

Confirmació de l'operació

D'aquesta manera es completa la implementació mínima requerida de l'autenticació de cookies. Proveu d'executar-lo i vegeu com funciona. El comportament hauria de canviar en funció de si heu iniciat la sessió o no. Com a exemple senzill, podeu veure el comportament següent.

Resultat
de l'operació ⇒ operació
Torna a casa sense iniciar sessió Redirecció a la pantalla d'inici de sessió
Connexió Anar a la pantalla d'inici
Tanca la sessió fora de casa i torna a casa sense iniciar sessió Redirecció a la pantalla d'inici de sessió
Torna a casa sense sortir de casa i iniciar sessió Anar a la pantalla d'inici