Erstellen Sie einen Anmeldemechanismus mithilfe der Cookie-Authentifizierung, und erstellen Sie einen Mechanismus, der umgeleitet wird, wenn Sie nicht authentifiziert sind

Diese Seite wurde aktualisiert :
Erstellungsdatum der Seite :

Betriebsumgebung

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

Zuerst

Dieses Mal wird ASP.NET Core die Cookie-Authentifizierung als Login-Authentifizierungsmechanismus verwenden. Sie können sich die Cookie-Authentifizierung ähnlich wie die herkömmliche Formularauthentifizierung vorstellen.

Ein weiterer Authentifizierungsmechanismus für ASP.NET Core ist ASP.NET Core Identity. Neben der Authentifizierung über Formulare können Sie sich damit mit APIs authentifizieren, externe Anmeldedienste nutzen, Passwörter verwalten und zurücksetzen usw. Sie können viele Funktionen verwenden. Wenn man dieses Mal jedoch nur einen einfachen Anmeldebildschirm erstellt, wird es sich um einen etwas übertriebenen Authentifizierungsmechanismus handeln. Wir werden es dieses Mal nicht verwenden.

In den dieses Mal eingeführten Tipps zur Cookie-Authentifizierung können Sie nur den Anmeldebildschirm anzeigen, wenn Sie sich anmelden. Wenn Sie versuchen, zu einem anderen Bildschirm zu navigieren, werden Sie zum Anmeldebildschirm weitergeleitet. Wenn Sie sich anmelden, können Sie andere Bildschirme anzeigen.

Vorerst können Sie sich anmelden, indem Sie Ihren Benutzernamen und Ihr Passwort auf dem Anmeldebildschirm eingeben. Die Benutzerauthentifizierung selbst wird als temporärer Ort implementiert. In diesem Fall liegt das Hauptaugenmerk auf der Implementierung der Cookie-Authentifizierung, so dass die Essenz des Bestimmungsprozesses, wie z. B. ob das Passwort korrekt ist, nicht das Wesentliche ist.

Dieser Tipp beschreibt nur einen Teil des Programms. Um den vollständigen Code zu erhalten, laden Sie das vollständige Programm herunter. Außerdem werden sowohl MVC- als auch Razor Pages-Frameworks behandelt.

Erstellen eines Projekts

Starten Sie Visual Studio, und erstellen Sie ein neues Projekt.

Wählen Sie für Razor Pages ASP.NET Core Web App aus, oder wählen Sie für MVC ASP.NET Core Web App (Model-View-Controller) aus.

Geben Sie einen Projektnamen Ihrer Wahl und einen Speicherort für das Projekt an.

Wählen Sie als Authentifizierungstyp "Keine" aus. Wenn Sie sich für eine andere Authentifizierung entscheiden, verwenden Sie ASP.NET Core Identity. Wenn Sie mit den Einstellungen fertig sind, klicken Sie auf die Schaltfläche "Erstellen".

Nach dem Erstellen des Projekts wird der unten gezeigte Bildschirm angezeigt, wenn das Debuggen ausgeführt wird. Auf der Grundlage dieses Bildschirms erstellen wir ein Programm.

Bearbeiten von Program.cs (Razor Pages, MVC Common)

Fügen Sie die für die Cookieauthentifizierung erforderlichen Definitionen zu Program.cs hinzu. Die hinzuzufügenden Namespaces lauten wie folgt:

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

Hier ist builder.Services der Code, der zu .

// === 省略 ===

// 「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 Sie können die Cookie-Authentifizierung aktivieren, indem Sie die and-Methode ausführen. Wenn Sie den Schemanamen nicht ändern müssen, CookieAuthenticationDefaults.AuthenticationScheme geben Sie an.

AddAuthorization Wenn Sie options.FallbackPolicy RequireAuthenticatedUser für die Methode Sie können eine Richtlinie anwenden, für die eine Authentifizierung erforderlich ist, und zwar auf alle Seiten, alle Controller und Aktionen. Wenn Sie eine Authentifizierung für etwas anderes als den Anmeldebildschirm anfordern möchten, ist dies eine nützliche Methode, um den Code zu reduzieren und Fehler in der Beschreibung zu vermeiden. Sie müssen Code, der keine Authentifizierung für den Anmeldebildschirm erfordert, separat schreiben.

Im Folgenden finden Sie app den Code für .

// === 省略 ===

app.UseRouting();

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

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

// === 省略 ===

Da wir der Anwendung Authentifizierungsfunktionen hinzufügen möchten, app.UseAuthentication() fügen wir . Der Speicherort der Beschreibung entspricht der MSDN-Dokumentation, app. UseAuthorization() verwenden. Ansonsten ist es immer noch eine Vorlage.

Programme für Razor Pages-Projekte

Erstellen einer Anmeldeseite (Pages/Account/Login.cshtml.cs)

Erstellen einer Datei

Erstellen Sie eine Anmeldeseite. Der Dateipfad sollte als "/Pages/Account/Login.cshtml" erstellt werden. Dies liegt daran, dass der Standard-Anmeldepfad so aussieht. Wenn Sie diesen Pfad ändern möchten, können Sie dies tun, indem Sie Program.cs das Argument der AddCookie Methode von festlegen.

Sie können es erstellen, indem Sie andere Dateien kopieren, anstatt es über das Menü zu erstellen, aber in diesem Fall korrigieren Sie bitte das Programm korrekt.

Benutzern den Zugriff auf die Anmeldeseite ohne Anmeldung erlauben

Program.cs Da alle Seiten nur aufgerufen werden können, wenn Sie eingeloggt sind, müssen Sie nur die Anmeldeseite so einstellen, dass Sie auch dann darauf zugreifen können, wenn Sie nicht angemeldet sind.

AllowAnonymous Durch das Hinzufügen von Attributen kann auf die Zielseite zugegriffen werden, auch wenn sie nicht authentifiziert ist. AllowAnonymous Attribute können auch an anderen Stellen als dem Anmeldebildschirm verwendet werden, z. B. API-Vorgänge, die nichts mit der Cookie-Authentifizierung zu tun haben.

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

Erstellen einer Variablen zum Empfangen von Eingaben

Wenn Sie sich anmelden, geben Sie Ihren Benutzernamen an, um diese Werte empfangen zu können, da Sie Ihr Passwort eingeben.

// 省略

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

Definieren Sie einen Benutzernamen und ein Passwort für die Anmeldeauthentifizierung

Ursprünglich sollte es in einer Datenbank usw. gespeichert werden, aber da das Urteilsvermögen der Benutzer dieses Mal nicht im Vordergrund steht, werde ich es zu einem temporären Ort machen.

// 省略

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

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

Login-Prozess

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

Dies ist der Authentifizierungsprozess nach dem Drücken der Anmeldetaste. Wenn der Benutzername und das Kennwort übereinstimmen, ist eine Authentifizierung möglich.

Der beschriebene Code ist der Mindestcode, der für die Authentifizierung erforderlich ist,ClaimClaimsIdentityClaimsPrincipal und HttpContext.SignInAsync Durch den Aufruf der Methode wird ein Cookie generiert und authentifiziert.

Wenn zusätzliche Ansprüche erforderlich sind oder ein Cookie-Ablauf erforderlich ist, werden zusätzliche Parameter hinzugefügt.

Nach der Anmeldung werden Sie zu weitergeleitet, wo /Index eine Authentifizierung erforderlich ist.

Abmeldevorgang

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

Logout Wenn mit einem Handler darauf zugegriffen wird, wird die Abmeldung verarbeitet. HttpContext.SignOutAsync Durch Aufrufen der Methode können Sie das Cookie löschen und in einen Zustand zurückversetzen, in dem Sie nicht angemeldet sind.

Erstellen einer Ansicht

Wir nehmen keine Rücksicht auf das Aussehen. Fügen Sie Felder zur Eingabe Ihres Benutzernamens und Passworts hinzu, wie unten gezeigt, und platzieren Sie eine Schaltfläche zum Anmelden. Sie sollten auch über einen Link verfügen, über den Sie zugreifen können, ohne sich zum /Index Testen anzumelden.

Da die Eingabe von Benutzername und Passwort umständlich ist, wird der Initialwert gesetzt.

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

Erstellen eines Abmeldelinks (/Pages/Shared/_Layout.cshtml)

Wir werden keine Änderungen am Startbildschirm vornehmen, aber wir werden einen Abmeldelink in die Navigationsleiste einfügen. Posten Sie zum Testen auch einen Link, der Sie zum Anmeldebildschirm führt, ohne sich abzumelden.

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

Das war's mit dem Razor Pages-Code.

Programme für MVC-Projekte

Erstellen eines Anmeldemodells

Sie haben ein Modell erstellt, um die auf dem Anmeldebildschirm eingegebenen Werte zu erhalten.

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

Erstellen eines AccountControllers

Erstellen Sie die Controller und Aktionen, die zum Erstellen des Anmeldebildschirms erforderlich sind. Erstellen Sie den Controllernamen AccountController als . Dies liegt daran, dass der Controllername und der Aktionsname auf dem Anmeldebildschirm standardmäßig auf "~/Account/Login" festgelegt sind. Wenn Sie diesen Pfad ändern möchten, können Sie dies in den Optionen der AddCookie Methode in Program.cs tun. Vorerst fahren wir mit den Standardeinstellungen fort.

Zuerst erstellen wir die Controller-Seite.

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 Durch das Gewähren des Attributs können alle darin enthaltenen Aktionen ausgeführt werden, ohne authentifiziert zu werden. Auf diese Weise können Sie ohne Authentifizierung nur auf den Anmeldebildschirm zugreifen.

AllowAnonymous Attribute können auch in reinen API-Controllern verwendet werden, die sich nicht auf die Cookie-Authentifizierung an anderen Stellen als dem Anmeldebildschirm beziehen.

Definieren Sie als Nächstes die Benutzer und Kennwörter, mit denen Sie sich anmelden können. Ursprünglich sollte es in einer Datenbank usw. gespeichert werden, aber da das Urteilsvermögen der Benutzer dieses Mal nicht im Vordergrund steht, werde ich es zu einem temporären Ort machen.

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

Im Folgenden finden Sie eine Aktion, mit der der Anmeldebildschirm angezeigt wird. Da sie nur angezeigt wird, wird die Ansicht so zurückgegeben, wie sie ist.

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

Nachfolgend finden Sie den Code, der beim Einloggen verarbeitet werden muss.

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

Dies ist der Authentifizierungsprozess nach dem Drücken der Anmeldetaste. Wenn der Benutzername und das Kennwort übereinstimmen, ist eine Authentifizierung möglich.

Der beschriebene Code ist der Mindestcode, der für die Authentifizierung erforderlich ist,ClaimClaimsIdentityClaimsPrincipal und HttpContext.SignInAsync Durch den Aufruf der Methode wird ein Cookie generiert und authentifiziert.

Wenn zusätzliche Ansprüche erforderlich sind oder ein Cookie-Ablauf erforderlich ist, werden zusätzliche Parameter hinzugefügt.

Nach der Anmeldung werden Sie zu weitergeleitet, wo ~/Home/Index eine Authentifizierung erforderlich ist.

Abschließend wird der Abmeldevorgang hinzugefügt.

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

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

HttpContext.SignOutAsync Durch Aufrufen der Methode können Sie das Cookie löschen und in einen Zustand zurückversetzen, in dem Sie nicht angemeldet sind.

Erstellen einer Ansicht (Anmeldeformular) (/Views/Account/Login.cshtml)

Login Klicken Sie mit der rechten Maustaste auf die Aktion, um eine Ansicht hinzuzufügen. Sie können es auch erstellen, indem Sie es aus einer anderen Datei kopieren.

Wir nehmen keine Rücksicht auf das Aussehen. Fügen Sie Felder zur Eingabe Ihres Benutzernamens und Passworts hinzu, wie unten gezeigt, und platzieren Sie eine Schaltfläche zum Anmelden. Sie sollten auch über einen Link verfügen, über den Sie zugreifen können, ohne sich zum Home/Index Testen anzumelden.

Da die Eingabe von Benutzername und Passwort umständlich ist, wird der Initialwert gesetzt.

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

Erstellen eines Abmeldelinks (/Views/Shared/_Layout.cshtml)

Wir werden keine Änderungen am Startbildschirm vornehmen, aber wir werden einen Abmeldelink in die Navigationsleiste einfügen. Posten Sie zum Testen auch einen Link, der Sie zum Anmeldebildschirm führt, ohne sich abzumelden.

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

Das war's mit dem MVC-Code.

Bestätigung des Betriebs

Damit ist die mindestens erforderliche Implementierung der Cookie-Authentifizierung abgeschlossen. Probieren Sie es aus und sehen Sie, wie es funktioniert. Das Verhalten sollte sich ändern, je nachdem, ob Sie angemeldet sind oder nicht. Als einfaches Beispiel können Sie das folgende Verhalten sehen.

Operation Vorgangsergebnis
Gehen Sie nach Hause, ohne sich anzumelden Zum Anmeldebildschirm umleiten
einloggen Gehen Sie zum Startbildschirm
Melden Sie sich von zu Hause ab und gehen Sie nach Hause, ohne sich anzumelden Zum Anmeldebildschirm umleiten
Gehen Sie nach Hause, ohne sich vom Haus abzumelden und anzumelden Gehen Sie zum Startbildschirm