إنشاء شاشات تسجيل دخول متعددة والحد من الصفحات التي يمكن الوصول إليها بواسطة الشاشة التي قمت بتسجيل الدخول إليها

تحديث الصفحة :
تاريخ إنشاء الصفحة :

بيئة التشغيل

فيجوال ستوديو
  • مجتمع فيجوال ستوديو 2022
ASP.NET الأساسية (MVC ، صفحات الحلاقة)
6.0

في البداية

يصف هذا القسم كيفية إعداد شاشات تسجيل دخول متعددة في تطبيق واحد وفصل الصفحات التي يمكن الوصول إليها بواسطة كل شاشة تسجيل دخول. يتم شرح طريقة إنشاء شاشة تسجيل دخول واحدة في "إنشاء آلية تسجيل دخول باستخدام مصادقة ملفات تعريف الارتباط وإنشاء آلية لإعادة توجيهك إذا لم تتم مصادقتك" ، ويتم شرح هذا المحتوى على افتراض أن لديك معرفة ببناء شاشة تسجيل دخول واحدة. لذلك ، فإن عملية نفس شاشة تسجيل الدخول الواحدة ليست سوى شرح بسيط.

إنشاء مشروع

أقوم بإنشاء عينة Razor Pages و MVC ، ولكن لا بأس في إنشاء المشروع الذي تريد استخدامه فقط.

تحرير البرنامج.cs (صفحات الحلاقة ، MVC المشتركة)

هذه المرة ، سنستخدم طريقة فصل الصفحات التي يمكن الوصول إليها عن طريق صفحة تسجيل الدخول باسم "المخطط".

أولا ، أضف مساحة الاسم إلى أعلى الكود.

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

ما يلي هو باني. رمز لإضافته إلى الخدمات.

// === 省略 ===

// 「Razor Pages」のコード
// builder.Services.AddRazorPages();
// 「MVC」のコード
// builder.Services.AddControllersWithViews();

// ※ここから追加

// Cookie による認証スキームを追加する
builder.Services
  .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
  .AddCookie("FirstAuth", option =>
  {
    option.LoginPath = "/Account/LoginFirst";
  })
  .AddCookie("SecondAuth", option =>
  {
    option.LoginPath = "/Account/LoginSecond";
  });

builder.Services.AddAuthorization(options =>
{
  // 認証属性を設定していない画面は FirstAuth スキーマの認証が必要となる
  options.FallbackPolicy = new AuthorizationPolicyBuilder("FirstAuth")
    .RequireAuthenticatedUser()
    .Build();
});

// ※ここまで追加

var app = builder.Build();

// === 省略 ===

الفرق من آخر مرة هو أن ملفات تعريف الارتباط تضاف إلى اثنين. AddCookie تحتوي الوسيطة الأولى لكل منها على اسم المخطط الذي يحدد تسجيل الدخول. يمكن أن يكون هذا الاسم أي شيء طالما أنه اسم مختلف. الوسيطة الثانية هي عنوان URL لصفحة تسجيل الدخول الذي سيتم إعادة توجيهه عند الوصول إلى تسجيل الدخول دون تسجيل الدخول. بالمناسبة ، إذا لم تحدد اسم مخطط ، CookieAuthenticationDefaults.AuthenticationScheme فسيكون هو نفسه .

FallbackPolicy كما يحدد المخطط كإعداد ل FirstAuth . نتيجة لذلك ، يلزم الوصول إلى FirstAuth هذه المصادقة التي لم تمسها Index.cshtml أو Privacy.cshtml المخطط.

رمز التطبيق التالي هو نفسه لتسجيل الدخول الفردي.

// === 省略 ===

app.UseRouting();

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

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

// === 省略 ===

برامج لمشاريع صفحات الحلاقة

إنشاء صفحة بعد تسجيل الدخول

قم بإنشاء صفحتين بعد تسجيل الدخول. نظرا لأنها صفحة يتم عرضها فقط ، فلا بأس إذا قمت بإنشائها حتى تتمكن من معرفة مكان تسجيل الدخول.

الصفحات/الفهرس فيرست.cshtml

@page
@model IndexFirstModel
@{
  ViewData["Title"] = "First page";
}

<div class="text-center">
    <h1 class="display-4">First Page</h1>
</div>

لا يوجد شيء مهم بشكل خاص حول هذا الموضوع ، ولكن تأكد من أن النموذج الذي تشير إليه يتطابق مع الصفحة التي IndexFirstModel أنشأتها ، مثل .

الصفحات/الفهرس فيرست.cshtml.cs

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace CookieAuthenticationMultipleRazorPages.Pages
{
  [Authorize(AuthenticationSchemes = "FirstAuth")]
  public class IndexFirstModel : PageModel
  {
    private readonly ILogger<IndexFirstModel> _logger;

    public IndexFirstModel(ILogger<IndexFirstModel> logger)
    {
      _logger = logger;
    }

    public void OnGet() { }
  }
}

لا توجد معالجة خاصة لأنه يتم عرضها فقط ، ولكن لاحظ أننا أضفنا كسمة لاسم Authorize الفئة. AuthenticationSchemes يتم تعيين الوسيطة إلى اسم المخطط المحدد في Program.cs. هذا يضمن أنه لا يمكنك عرض هذه الصفحة إلا إذا قمت بتسجيل الدخول باستخدام اسم المخطط هذا. إذا قمت بزيارة هذه الصفحة دون تسجيل الدخول ، فستتم إعادة توجيهك إلى صفحة تسجيل الدخول.

الصفحات/الفهرس الثاني.cshtml

هذه هي الصفحة الثانية بعد تسجيل الدخول.

@page
@model IndexSecondModel
@{
  ViewData["Title"] = "Second page";
}

<div class="text-center">
  <h1 class="display-4">Second Page</h1>
</div>

الصفحات/الفهرس الثاني.cshtml.cs

لاحظ أن الرمز هو في الأساس نفس صفحة تسجيل الدخول الأولى ، لكن اسم المخطط مختلف.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace CookieAuthenticationMultipleRazorPages.Pages
{
  [Authorize(AuthenticationSchemes = "SecondAuth")]
  public class IndexSecondModel : PageModel
  {
    private readonly ILogger<IndexSecondModel> _logger;

    public IndexSecondModel(ILogger<IndexSecondModel> logger)
    {
      _logger = logger;
    }

    public void OnGet() { }
  }
}

إنشاء صفحة تسجيل دخول

إنشاء صفحتين لتسجيل الدخول.

الصفحات/الحساب/LoginFirst.cshtml.cs

ألحق السمة بحيث يمكنك الوصول إليها دون AllowAnonymous تسجيل الدخول.

using Microsoft.AspNetCore.Authentication;
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 CookieAuthenticationMultipleRazorPages.Pages.Account
{
  [AllowAnonymous]
  public class LoginFirstModel : PageModel
  {
  }
}

قم بإنشاء متغير وحساب مستخدم وهمي لتلقي معلومات تسجيل الدخول التي أدخلتها.

[AllowAnonymous]
public class LoginFirstModel : PageModel
{
  /// <summary>ユーザー名。</summary>
  [BindProperty]
  [Required]
  [DisplayName("ユーザー名")]
  public string UserName { get; set; } = "";

  /// <summary>パスワード。</summary>
  [BindProperty]
  [Required]
  [DataType(DataType.Password)]
  [DisplayName("パスワード")]
  public string Password { get; set; } = "";

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

فيما يلي عملية تسجيل الدخول.

/// <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, "FirstAuth");
  var principal = new ClaimsPrincipal(identity);

  // 認証クッキーをレスポンスに追加
  await HttpContext.SignInAsync("FirstAuth", principal);

  // ログインが必要な画面にリダイレクトします
  return RedirectToPage("/IndexFirst");
}

الفرق من تسجيل دخول واحد هو أنه يتم تحديد كل اسم مخطط. الموقع الذي تحدده هو ClaimsIdentity وسيطة HttpContext.SignInAsync ووسيطة . هنا يمكنك تحديد المخطط الذي تريد تسجيل الدخول به.

تسجيل الخروج هو أيضا في شكل تحديد اسم المخطط.

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

الصفحات/الحساب/LoginFirst.cshtml

لا يختلف جانب العرض عن تسجيل دخول واحد. يرجى مطابقة اسم الطراز المراد الرجوع إليه.

@page
@model LoginFirstModel
@{}

<p>Login1</p>

<form method="post">
  <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="/IndexFirst">認証が必要な画面へ直接リンク</a>
    </div>
  </div>
</form>

@section Scripts {
  @{
    await Html.RenderPartialAsync("_ValidationScriptsPartial");
  }
}

الصفحات/الحساب/LoginSecond.cshtml.cs

إليك منطق تسجيل دخول آخر. First Second الأمر مختلف تماما.

using Microsoft.AspNetCore.Authentication;
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 CookieAuthenticationMultipleRazorPages.Pages.Account
{
  [AllowAnonymous]
  public class LoginSecondModel : PageModel
  {
    /// <summary>ユーザー名。</summary>
    [BindProperty]
    [Required]
    [DisplayName("ユーザー名")]
    public string UserName { get; set; } = "";

    /// <summary>パスワード。</summary>
    [BindProperty]
    [Required]
    [DataType(DataType.Password)]
    [DisplayName("パスワード")]
    public string Password { get; set; } = "";

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

    /// <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, "SecondAuth");
      var principal = new ClaimsPrincipal(identity);

      // 認証クッキーをレスポンスに追加
      await HttpContext.SignInAsync("SecondAuth", principal);

      // ログインが必要な画面にリダイレクトします
      return RedirectToPage("/IndexSecond");
    }

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

الصفحات/الحساب/LoginSecond.cshtml

منظر. First انها مجرد ذلك ومختلفة Second .

@page
@model LoginSecondModel
@{}

<p>Login Second</p>

<form method="post">
  <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="/IndexSecond">認証が必要な画面へ直接リンク</a>
    </div>
  </div>
</form>

@section Scripts {
  @{
    await Html.RenderPartialAsync("_ValidationScriptsPartial");
  }
}

الصفحات/المشتركة/_Layout.cshtml

أضف رابط تسجيل خروج لكل منها.

<!-- 中略 -->
<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/LoginFirst" asp-page-handler="Logout">ログアウト(First)</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-page="/Account/LoginFirst">ログアウトせずログインへ(First)</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-page="/Account/LoginSecond" asp-page-handler="Logout">ログアウト(Second)</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-page="/Account/LoginSecond">ログアウトせずログインへ(Second)</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-page="/IndexFirst">IndexFirst</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-page="/IndexSecond">IndexSecond</a>
    </li>
    <!-- ここまで追加 -->
  </ul>
</div>
<!-- 中略 -->

برامج لمشاريع MVC

إنشاء نموذج تسجيل دخول

هذه المرة ، قيم الإدخال لشاشتي تسجيل الدخول هي نفسها ، لذلك سنشاركها وننشئ واحدة فقط.

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace CookieAuthenticationMultipleMvc.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 تضمين عمليتي تسجيل الدخول في ، لذلك ما عليك سوى إضافة وحدة تحكم واحدة.

AllowAnonymous نسبها بحيث يمكنك الوصول إليها دون تسجيل الدخول.

using CookieAuthenticationMultipleMvc.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

namespace CookieAuthenticationMultipleMvc.Controllers
{
  /// <remarks>
  /// <see cref="AllowAnonymous"/> 属性は Cookie 認証していなくてもアクセスできる Action (Controller) であることを示す。
  /// </remarks>
  [AllowAnonymous]
  public class AccountController : Controller
  {
  }
}

إنشاء حساب مستخدم وهمي.

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

أضف إجراء لعرض الصفحة لتسجيل الدخول الأول.

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

يوجد أدناه الرمز المراد معالجته عند تسجيل الدخول.

/// <summary>ログイン処理を実行します。</summary>
[HttpPost]
public async Task<IActionResult> LoginFirst(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, "FirstAuth");
  var principal = new ClaimsPrincipal(identity);

  // 認証クッキーをレスポンスに追加
  await HttpContext.SignInAsync("FirstAuth", principal);

  // ログインが必要な画面にリダイレクトします
  return RedirectToAction(nameof(HomeController.Index), "HomeFirst");
}

الفرق من تسجيل دخول واحد هو أنه يتم تحديد كل اسم مخطط. الموقع الذي تحدده هو ClaimsIdentity وسيطة HttpContext.SignInAsync ووسيطة . هنا يمكنك تحديد المخطط الذي تريد تسجيل الدخول به.

تسجيل الخروج هو أيضا في شكل تحديد اسم المخطط.

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

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

سأضيف أيضا تسجيل الدخول الثاني. First لا يوجد فرق آخر بمجرد تغيير جزء من Second .

// 中略

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

/// <summary>ログイン処理を実行します。</summary>
[HttpPost]
public async Task<IActionResult> LoginSecond(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, "SecondAuth");
  var principal = new ClaimsPrincipal(identity);

  // 認証クッキーをレスポンスに追加
  await HttpContext.SignInAsync("SecondAuth", principal);

  // ログインが必要な画面にリダイレクトします
  return RedirectToAction(nameof(HomeController.Index), "HomeSecond");
}

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

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

// 中略

إنشاء طريقة عرض (نموذج تسجيل الدخول)

إنشاء طريقتي عرض لكل منهما.

لا يوجد فرق كبير بين تسجيل دخول واحد ورمز ، لذلك سأقوم بنشر الرمز كما هو.

وجهات النظر/الحساب/LoginFirst.cshtml

@model LoginModel
@{}

<h1>Login First</h1>

<form asp-action="LoginFirst">
  <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="HomeFirst" asp-action="Index">認証が必要な画面へ直接リンク</a>
    </div>
  </div>
</form>

@section Scripts {
  @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

وجهات النظر/الحساب/LoginSecond.cshtml

@model LoginModel
@{}

<h1>Login Second</h1>

<form asp-action="LoginSecond">
  <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="HomeSecond" asp-action="Index">認証が必要な画面へ直接リンク</a>
    </div>
  </div>
</form>

@section Scripts {
  @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

إنشاء الشاشة بعد تسجيل الدخول

HomeController قم بإنشاء وحدتي تحكم جديدتين دون استخدام وحدة التحكم الموجودة. هذه هي وحدات التحكم التي يمكنك الوصول إليها بعد تسجيل الدخول. يتم تعيين كل شاشة بحيث يمكن الوصول إليها بشكل مختلف اعتمادا على الشاشة التي قمت بتسجيل الدخول إليها.

الصفحة الرئيسيةأولاالمراقب المالي.cs

نظرا لأنه يعرض الشاشة فقط ، فلا يوجد شيء لإضافة المعالجة.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace CookieAuthenticationMultipleMvc.Controllers
{
  [Authorize(AuthenticationSchemes = "FirstAuth")]
  public class HomeFirstController : Controller
  {
    public IActionResult Index() => View();
  }
}

بدلا من ذلك ، يقوم بإرفاق سمة بوحدة التحكم ويحدد AuthenticationSchemes اسم المخطط كوسيطةAuthorize. FirstAuth يضمن ذلك أنه لا يمكنك الوصول إلى وحدة التحكم هذه إلا إذا كنت تقوم بالمصادقة باستخدام المخطط.

الصفحة الرئيسيةالثانيةالمراقب المالي.cs

Second قم بإنشاء الجانب بنفس الطريقة.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace CookieAuthenticationMultipleMvc.Controllers
{
  [Authorize(AuthenticationSchemes = "SecondAuth")]
  public class HomeSecondController : Controller
  {
    public IActionResult Index() => View();
  }
}

وجهات النظر/الصفحة الرئيسية أولا/Index.cshtml

لا يوجد شيء صعب بشكل خاص لأنه يتم عرضه للتو. ميزها حتى تتمكن من رؤية الصفحة التي هي عليها.

@{
  ViewData["Title"] = "First View";
}

<div class="text-center">
  <h1 class="display-4">First View</h1>
</div>

وجهات النظر/الصفحة الرئيسية/Index.cshtml

فقط أظهرها هنا أيضا.

@{
  ViewData["Title"] = "Second View";
}

<div class="text-center">
  <h1 class="display-4">Second View</h1>
</div>

المشاهدات / المشتركة / _Layout.cshtml

أضف رابط تسجيل خروج لكل منها.

<!-- 中略 -->
<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-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="LogoutFirst">ログアウト(First)</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-controller="Account" asp-action="LoginFirst">ログアウトせずログインへ(First)</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-controller="Account" asp-action="LogoutSecond">ログアウト(Second)</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-controller="Account" asp-action="LoginSecond">ログアウトせずログインへ(Second)</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-controller="HomeFirst" asp-action="Index">IndexFirst</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-controller="HomeSecond" asp-action="Index">IndexSecond</a>
    </li>
    <!-- ここまで追加 -->
  </ul>
</div>
<!-- 中略 -->

تأكيد العملية

يرجى تشغيله لترى كيف يعمل. أنا متأكد من أنك رأيت بالفعل عمل تسجيل الدخول الفردي ، لذلك أعتقد أنه من الجيد التحقق مما يحدث عند الوصول إلى كل شاشة عند الاحتفاظ بحالة تسجيل الدخول في النمط التالي.

  • لم يتم تسجيل الدخول الأول ولا الثاني
  • الأول تم تسجيل الدخول والثاني لم يتم تسجيل الدخول
  • الأول لم يتم تسجيل الدخول، الثاني لم يتم تسجيل الدخول
  • يتم تسجيل الدخول إلى كل من الأول والثاني