Δημιουργήστε πολλαπλές οθόνες σύνδεσης και περιορίστε τις σελίδες στις οποίες μπορείτε να έχετε πρόσβαση από την οθόνη στην οποία είστε συνδεδεμένοι

Σελίδα ενημέρωση :
Ημερομηνία δημιουργίας σελίδας :

Περιβάλλον λειτουργίας

Οπτικό στούντιο
  • Κοινότητα Visual Studio 2022
ASP.NET Core (MVC, Σελίδες ξυραφιού)
6.0

Αρχικά

Αυτή η ενότητα περιγράφει πώς να προετοιμάσετε πολλαπλές οθόνες σύνδεσης σε μία εφαρμογή και να διαχωρίσετε τις σελίδες στις οποίες μπορείτε να έχετε πρόσβαση από κάθε οθόνη σύνδεσης. Η μέθοδος δημιουργίας μιας ενιαίας οθόνης σύνδεσης εξηγείται στην ενότητα "Δημιουργία μηχανισμού σύνδεσης χρησιμοποιώντας έλεγχο ταυτότητας cookie και δημιουργία μηχανισμού ανακατεύθυνσης εάν δεν έχετε πιστοποιηθεί" και αυτό το περιεχόμενο εξηγείται με την προϋπόθεση ότι έχετε γνώση της δημιουργίας μιας ενιαίας οθόνης σύνδεσης. Επομένως, η διαδικασία του ίδιου με μια ενιαία οθόνη σύνδεσης είναι μόνο μια απλή εξήγηση.

Δημιουργία έργου

Δημιουργώ ένα δείγμα Razor Pages και MVC, αλλά είναι εντάξει να δημιουργήσετε μόνο το έργο που θέλετε να χρησιμοποιήσετε.

Επεξεργασία προγράμματος.cs (Razor Pages, MVC Common)

Αυτή τη φορά, θα χρησιμοποιήσουμε τη μέθοδο διαχωρισμού των σελίδων στις οποίες μπορεί να έχει πρόσβαση η σελίδα σύνδεσης με το όνομα "σχήμα".

Αρχικά, προσθέστε τον χώρο ονομάτων στο επάνω μέρος του κώδικα.

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();

// === 省略 ===

Η διαφορά από την τελευταία φορά είναι ότι τα cookies προστίθενται σε δύο. 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?}");

// === 省略 ===

Προγράμματα για έργα Razor Pages

Δημιουργία σελίδας μετά τη σύνδεση

Δημιουργήστε δύο σελίδες αφού συνδεθείτε. Δεδομένου ότι είναι μια σελίδα που εμφανίζεται μόνο, είναι εντάξει αν το κάνετε έτσι ώστε να μπορείτε να δείτε πού είστε συνδεδεμένοι.

Σελίδες/IndexFirst.cshtml

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

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

Δεν υπάρχει τίποτα ιδιαίτερα σημαντικό σε αυτό, αλλά βεβαιωθείτε ότι το μοντέλο στο οποίο αναφέρεστε ταιριάζει με τη IndexFirstModel σελίδα που δημιουργήσατε, όπως .

Σελίδες/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. Αυτό διασφαλίζει ότι μπορείτε να προβάλετε αυτήν τη σελίδα μόνο εάν συνδεθείτε με αυτό το όνομα σχήματος. Εάν επισκεφθείτε αυτήν τη σελίδα χωρίς να συνδεθείτε, θα μεταφερθείτε στη σελίδα σύνδεσης.

Σελίδες/IndexSecond.cshtml

Αυτή είναι η δεύτερη σελίδα μετά τη σύνδεση.

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

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

Σελίδες/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");
}

Η διαφορά από μία μόνο σύνδεση είναι ότι καθορίζεται κάθε όνομα σχήματος. Η θέση που καθορίζετε είναι 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

Οι δύο διαδικασίες 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 Δημιουργήστε δύο νέους ελεγκτές χωρίς να χρησιμοποιήσετε τον υπάρχοντα. Αυτοί είναι οι ελεγκτές στους οποίους μπορείτε να αποκτήσετε πρόσβαση αφού συνδεθείτε. Κάθε οθόνη έχει ρυθμιστεί ώστε να είναι προσβάσιμη διαφορετικά ανάλογα με την οθόνη στην οποία συνδεθήκατε.

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 Αυτό εξασφαλίζει ότι μπορείτε να αποκτήσετε πρόσβαση σε αυτόν τον ελεγκτή μόνο εάν πραγματοποιείτε έλεγχο ταυτότητας με το σχήμα.

ΑρχικήSecondController.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>

Προβολές/HomeSecond/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>
<!-- 中略 -->

Επιβεβαίωση λειτουργίας

Εκτελέστε το για να δείτε πώς λειτουργεί. Είμαι βέβαιος ότι έχετε ήδη δει την ενιαία σύνδεση να λειτουργεί, οπότε Νομίζω ότι είναι καλή ιδέα να ελέγξετε τι συμβαίνει όταν αποκτάτε πρόσβαση σε κάθε οθόνη όταν διατηρείτε την κατάσταση σύνδεσης στο ακόλουθο μοτίβο.

  • Ούτε ο πρώτος ούτε ο δεύτερος είναι συνδεδεμένοι
  • Ο πρώτος είναι συνδεδεμένος και ο δεύτερος δεν είναι συνδεδεμένος
  • Ο πρώτος δεν είναι συνδεδεμένος, ο δεύτερος είναι συνδεδεμένος
  • Τόσο ο πρώτος όσο και ο δεύτερος είναι συνδεδεμένοι