Maak meerdere inlogschermen aan en beperk de pagina's die toegankelijk zijn voor het scherm waarop u bent ingelogd

Pagina bijgewerkt :
Aanmaakdatum van pagina :

Werkomgeving

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

Eerst

In dit gedeelte wordt beschreven hoe u meerdere aanmeldingsschermen in één toepassing kunt voorbereiden en de pagina's kunt scheiden die door elk aanmeldingsscherm kunnen worden geopend. De methode voor het bouwen van een enkel inlogscherm wordt uitgelegd in "Een inlogmechanisme maken met behulp van cookie-authenticatie en een mechanisme creëren om te worden omgeleid als u niet bent geauthenticeerd", en deze inhoud wordt uitgelegd in de veronderstelling dat u kennis heeft van het bouwen van een enkel inlogscherm. Daarom is het proces van hetzelfde als een enkel inlogscherm slechts een eenvoudige uitleg.

Een project maken

Ik ben bezig met het maken van een Razor Pages en MVC-voorbeeld, maar het is prima om alleen het project te maken dat u wilt gebruiken.

Programma bewerken.cs (Razor Pages, MVC Common)

Deze keer zullen we de methode gebruiken om de pagina's die toegankelijk zijn voor de inlogpagina te scheiden met de naam "schema".

Voeg eerst de naamruimte toe aan de bovenkant van de code.

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

Het volgende is een bouwer. Code om toe te voegen aan Services.

// === 省略 ===

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

// === 省略 ===

Het verschil met de vorige keer is dat er twee cookies worden toegevoegd. AddCookie Het eerste argument van elk bevat de schemanaam die de aanmelding identificeert. Deze naam kan van alles zijn, zolang het maar een andere naam is. Het tweede argument is de URL van de inlogpagina die wordt omgeleid wanneer een login wordt geopend zonder in te loggen. Trouwens, als u geen schemanaam opgeeft, is deze CookieAuthenticationDefaults.AuthenticationScheme hetzelfde als .

FallbackPolicy Het specificeert ook het schema als de instelling voor FirstAuth . Als gevolg hiervan is toegang tot FirstAuth deze onaangeroerde Index.cshtml of Privacy.cshtml schema-authenticatie vereist.

De code voor de volgende app is dezelfde als voor een enkele login.

// === 省略 ===

app.UseRouting();

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

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

// === 省略 ===

Programma's voor Razor Pages-projecten

Een pagina aanmaken na inloggen

Maak twee pagina's aan nadat je bent ingelogd. Aangezien het een pagina is die alleen wordt weergegeven, is het OK als u deze zo maakt dat u kunt zien waar u bent ingelogd.

Pagina's/IndexFirst.cshtml

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

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

Er is niets bijzonders aan, maar zorg ervoor dat het model waarnaar u verwijst overeenkomt met de IndexFirstModel pagina die u hebt gemaakt, zoals .

Pagina's/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() { }
  }
}

Er is geen speciale behandeling omdat het alleen wordt weergegeven, maar merk op dat we hebben toegevoegd als een attribuut van Authorize de klassenaam. AuthenticationSchemes Het argument wordt ingesteld op de schemanaam die is opgegeven in Programma.cs. Dit zorgt ervoor dat je deze pagina alleen kunt bekijken als je inlogt met deze schemanaam. Als u deze pagina bezoekt zonder in te loggen, wordt u doorgestuurd naar de inlogpagina.

Pagina's/IndexSecond.cshtml

Dit is de tweede pagina na inloggen.

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

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

Pagina's/IndexSecond.cshtml.cs

Merk op dat de code in principe hetzelfde is als de eerste inlogpagina, maar dat de schemanaam anders is.

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

Een inlogpagina maken

Maak twee inlogpagina's aan.

Pagina's/Account/LoginFirst.cshtml.cs

Voeg het attribuut toe zodat u het kunt openen zonder AllowAnonymous in te loggen.

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

Maak een variabel en een dummy-gebruikersaccount aan om de door u ingevoerde inloggegevens te ontvangen.

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

Het volgende is het inlogproces.

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

Het verschil met een enkele aanmelding is dat elke schemanaam wordt opgegeven. De locatie die u opgeeft is ClaimsIdentity het argument van en het argument van HttpContext.SignInAsync . Hier kun je aangeven met welk schema je wilt inloggen.

Afmelden is ook in de vorm van het opgeven van de schemanaam.

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

Pagina's/Account/LoginFirst.cshtml

De weergavezijde verschilt niet van een enkele login. Zorg ervoor dat de modelnaam waarnaar moet worden verwezen, overeenkomen.

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

Pagina's/Account/LoginSecond.cshtml.cs

Hier is nog een inloglogica. First Second Het is gewoon anders.

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

Pagina's/Account/LoginSecond.cshtml

Bekijken. First Het is gewoon dat en Second zijn anders.

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

Pagina's/Gedeeld/_Layout.cshtml

Voeg voor elk een uitloglink toe.

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

Programma's voor MVC-projecten

Een inlogmodel maken

Deze keer zijn de invoerwaarden van de twee inlogschermen hetzelfde, dus we zullen ze delen en er maar één maken.

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

Een AccountController aanmaken

De twee inlogprocessen zijn AccountController opgenomen in , dus u hoeft slechts één controller toe te voegen.

AllowAnonymous Schrijf het toe zodat u er toegang toe hebt zonder in te loggen.

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

Maak een dummy-gebruikersaccount aan.

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

Voeg een actie toe om de pagina weer te geven voor de eerste keer inloggen.

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

Hieronder vindt u de code die moet worden verwerkt bij het inloggen.

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

Het verschil met een enkele aanmelding is dat elke schemanaam wordt opgegeven. De locatie die u opgeeft is ClaimsIdentity het argument van en het argument van HttpContext.SignInAsync . Hier kun je aangeven met welk schema je wilt inloggen.

Afmelden is ook in de vorm van het opgeven van de schemanaam.

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

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

Ik zal ook de tweede login toevoegen. First Er is geen ander verschil door alleen het deel van Second te veranderen.

// 中略

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

// 中略

Een weergave maken (inlogformulier)

Maak elk twee weergaven.

Er is niet veel verschil tussen een enkele login en een code, dus ik zal de code posten zoals hij is.

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

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

Scherm aanmaken na inloggen

HomeController Maak twee nieuwe controllers zonder de bestaande te gebruiken. Dit zijn de controllers waartoe u toegang hebt nadat u bent ingelogd. Elk scherm is zo ingesteld dat het anders toegankelijk is, afhankelijk van het scherm waarop u bent ingelogd.

HomeFirstController.cs

Omdat het alleen het scherm weergeeft, is er niets om verwerking toe te voegen.

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

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

In plaats daarvan wordt een attribuut aan de controller gekoppeld en AuthenticationSchemes wordt de naam van het schema als argument Authorize opgegeven. FirstAuth Dit zorgt ervoor dat u alleen toegang hebt tot deze controller als u zich authenticeert met het schema.

HomeSecondController.cs

Second Maak de zijkant op dezelfde manier.

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

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

Weergaven/HomeFirst/Index.cshtml

Er is niets bijzonders moeilijks omdat het gewoon wordt weergegeven. Onderscheid ze zodat je kunt zien om welke pagina het gaat.

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

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

Weergaven/HomeSecond/Index.cshtml

Laat het hier ook zien.

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

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

Weergaven/Gedeeld/_Layout.cshtml

Voeg voor elk een uitloglink toe.

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

Bevestiging van de werking

Voer het uit om te zien hoe het werkt. Ik weet zeker dat je de single login al hebt zien werken, dus Ik denk dat het een goed idee is om te controleren wat er gebeurt als je elk scherm opent als je de inlogstatus in het volgende patroon houdt.

  • Noch de eerste, noch de tweede zijn ingelogd
  • De eerste is ingelogd en de tweede is niet ingelogd
  • De eerste is niet ingelogd, de tweede is ingelogd
  • Zowel de eerste als de tweede zijn ingelogd