एकाधिक लॉगिन स्क्रीन बनाएं और उन पृष्ठों को सीमित करें जिन्हें आपके द्वारा लॉग इन की गई स्क्रीन द्वारा एक्सेस किया जा सकता है

पेज अद्यतन :
पेज निर्माण की तारीख :

ऑपरेटिंग वातावरण

विजुअल स्टूडियो
  • विजुअल स्टूडियो कम्युनिटी 2022
ASP.NET कोर (MVC, रेजर पेज)
6.0

पहले

यह खंड वर्णन करता है कि एक एप्लिकेशन में कई लॉगिन स्क्रीन कैसे तैयार करें और उन पृष्ठों को अलग करें जिन्हें प्रत्येक लॉगिन स्क्रीन द्वारा एक्सेस किया जा सकता है। एकल लॉगिन स्क्रीन बनाने की विधि को "कुकी प्रमाणीकरण का उपयोग करके एक लॉगिन तंत्र बनाना और यदि आप प्रमाणित नहीं हैं तो पुनर्निर्देशित करने के लिए एक तंत्र बनाना" में समझाया गया है, और इस सामग्री को इस धारणा पर समझाया गया है कि आपको एकल लॉगिन स्क्रीन बनाने का ज्ञान है। इसलिए, एकल लॉगिन स्क्रीन के समान की प्रक्रिया केवल एक सरल व्याख्या है।

एक परियोजना बनाएँ

मैं एक रेजर पेज और एमवीसी नमूना बना रहा हूं, लेकिन केवल उस प्रोजेक्ट को बनाना ठीक है जिसका आप उपयोग करना चाहते हैं।

संपादन कार्यक्रम.cs (रेजर पेज, एमवीसी कॉमन)

इस बार, हम उन पृष्ठों को अलग करने की विधि का उपयोग करेंगे जिन्हें लॉगिन पृष्ठ द्वारा "स्कीमा" के नाम से एक्सेस किया जा सकता है।

सबसे पहले, कोड के शीर्ष पर नामस्थान जोड़ें।

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 को . परिणामस्वरूप, इस अछूते Index.cshtml या Privacy.cshtml स्कीमा प्रमाणीकरण तक FirstAuth पहुंच की आवश्यकता होती है।

निम्नलिखित ऐप के लिए कोड एकल लॉगिन के समान है।

// === 省略 ===

app.UseRouting();

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

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

// === 省略 ===

रेजर पेज परियोजनाओं के लिए कार्यक्रम

लॉग इन करने के बाद पेज बनाना

लॉग इन करने के बाद दो पेज बनाएं। चूंकि यह एक ऐसा पृष्ठ है जो केवल प्रदर्शित होता है, यदि आप इसे बनाते हैं तो यह ठीक है ताकि आप देख सकें कि आप कहां लॉग इन हैं।

पृष्ठ/IndexFirst.cshtml

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

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

इसके बारे में विशेष रूप से महत्वपूर्ण कुछ भी नहीं है, लेकिन सुनिश्चित करें कि आप जिस मॉडल का संदर्भ दे रहे हैं वह आपके द्वारा बनाए गए पृष्ठ से IndexFirstModel मेल खाता है, जैसे कि .

Pages/IndexFirst.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 तर्क प्रोग्राम.cs में निर्दिष्ट स्कीमा नाम पर सेट है। यह सुनिश्चित करता है कि आप इस पृष्ठ को केवल तभी देख सकते हैं जब आप इस स्कीमा नाम से लॉग इन करते हैं। यदि आप लॉग इन किए बिना इस पृष्ठ पर जाते हैं, तो आपको लॉगिन पृष्ठ पर पुनः निर्देशित किया जाएगा।

Pages/IndexSecond.cshtml

लॉगिन के बाद यह दूसरा पेज है।

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

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

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

एकल लॉगिन से अंतर यह है कि प्रत्येक स्कीमा नाम निर्दिष्ट है। आपके द्वारा निर्दिष्ट स्थान का HttpContext.SignInAsync तर्क और तर्क हैClaimsIdentity। यहां आप निर्दिष्ट कर सकते हैं कि आप किस स्कीमा के साथ लॉग इन करना चाहते हैं।

लॉगआउट स्कीमा नाम निर्दिष्ट करने के रूप में भी है।

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

पृष्ठ/खाता/लॉगिनसेकंड.सीएसएचटीएमएल

देखना। 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>
<!-- 中略 -->

एमवीसी परियोजनाओं के लिए कार्यक्रम

लॉगिन मॉडल बनाना

इस बार, दो लॉगिन स्क्रीन के इनपुट वैल्यू समान हैं, इसलिए हम उन्हें साझा करेंगे और केवल एक ही बनाएंगे।

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

एकल लॉगिन से अंतर यह है कि प्रत्येक स्कीमा नाम निर्दिष्ट है। आपके द्वारा निर्दिष्ट स्थान का HttpContext.SignInAsync तर्क और तर्क हैClaimsIdentity। यहां आप निर्दिष्ट कर सकते हैं कि आप किस स्कीमा के साथ लॉग इन करना चाहते हैं।

लॉगआउट स्कीमा नाम निर्दिष्ट करने के रूप में भी है।

/// <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 मौजूदा एक का उपयोग किए बिना दो नए नियंत्रक बनाएं। ये वे नियंत्रक हैं जिन्हें आप लॉग इन करने के बाद एक्सेस कर सकते हैं। आपके द्वारा लॉग इन की गई स्क्रीन के आधार पर प्रत्येक स्क्रीन को अलग-अलग तरीके से एक्सेस करने योग्य बनाया गया है।

HomeFirstController.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();
  }
}

दृश्य/HomeFirst/Index.cshtml

विशेष रूप से मुश्किल कुछ भी नहीं है क्योंकि यह सिर्फ प्रदर्शित होता है। उन्हें अलग करें ताकि आप देख सकें कि यह कौन सा पृष्ठ है।

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

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

दृश्य/होमसेकंड/इंडेक्स.सीएसएचटीएमएल

बस इसे यहां भी दिखाएं।

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

ऑपरेशन की पुष्टि

कृपया यह देखने के लिए इसे चलाएं कि यह कैसे काम करता है। मुझे यकीन है कि आपने पहले ही एकल लॉगिन कार्य देखा है, इसलिए मुझे लगता है कि यह जांचना एक अच्छा विचार है कि जब आप प्रत्येक स्क्रीन तक पहुंचते हैं तो क्या होता है जब आप लॉगिन स्थिति को निम्न पैटर्न में रखते हैं।

  • न तो पहला और न ही दूसरा लॉग इन है
  • पहला लॉग इन है और दूसरा लॉग इन नहीं है
  • पहला लॉग इन नहीं है, दूसरा लॉग इन है
  • पहले और दूसरे दोनों लॉग इन हैं