Créez plusieurs écrans de connexion et limitez les pages accessibles par l’écran auquel vous êtes connecté.
Environnement d’exploitation
- Visual Studio
-
- Communauté Visual Studio 2022
- ASP.NET Core (MVC, Razor Pages)
- 6.0
Au début
Cette section décrit comment préparer plusieurs écrans de connexion dans une application et séparer les pages accessibles par chaque écran de connexion. La méthode de construction d’un écran de connexion unique est expliquée dans « Création d’un mécanisme de connexion à l’aide de l’authentification par cookie et création d’un mécanisme de redirection si vous n’êtes pas authentifié », et ce contenu est expliqué en supposant que vous avez des connaissances sur la construction d’un écran de connexion unique. Par conséquent, le processus de la même chose qu’un écran de connexion unique n’est qu’une explication simple.
Créer un projet
Je suis en train de créer un exemple Razor Pages et MVC, mais vous pouvez créer uniquement le projet que vous souhaitez utiliser.
Modifier le programme.cs (Razor Pages, MVC Common)
Cette fois-ci, nous allons utiliser la méthode qui consiste à séparer les pages accessibles par la page de connexion par le nom de « schéma ».
Tout d’abord, ajoutez l’espace de noms en haut du code.
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
Ce qui suit est un constructeur. Code à ajouter aux 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();
// === 省略 ===
La différence par rapport à la dernière fois, c’est que les cookies sont ajoutés à deux.
AddCookie
Le premier argument de chacun contient le nom du schéma qui identifie la connexion. Ce nom peut être n’importe quoi tant qu’il s’agit d’un nom différent.
Le deuxième argument est l’URL de la page de connexion qui sera redirigée lorsqu’une connexion est accédée sans se connecter.
Soit dit en passant, si vous ne spécifiez pas de nom de schéma, il CookieAuthenticationDefaults.AuthenticationScheme
sera identique à .
FallbackPolicy
Il spécifie également le schéma en tant que paramètre pour FirstAuth
. Par conséquent, l’accès à FirstAuth
cette authentification intacte Index.cshtml
ou Privacy.cshtml
par schéma est requis.
Le code de l’application suivante est le même que pour une connexion unique.
// === 省略 ===
app.UseRouting();
app.UseAuthentication(); // [追加] 認証
app.UseAuthorization(); // 認可
// 「Razor Pages」のコード
// app.MapRazorPages();
// 「MVC」のコード
// app.MapControllerRoute(
// name: "default",
// pattern: "{controller=Home}/{action=Index}/{id?}");
// === 省略 ===
Programmes pour les projets Razor Pages
Création d’une page après s’être connecté
Créez deux pages après vous être connecté. Puisqu’il s’agit d’une page qui ne fait que s’afficher, il n’y a pas de problème si vous faites en sorte que vous puissiez voir où vous êtes connecté.
Pages/IndexFirst.cshtml
@page
@model IndexFirstModel
@{
ViewData["Title"] = "First page";
}
<div class="text-center">
<h1 class="display-4">First Page</h1>
</div>
Il n’y a rien de particulièrement important à ce sujet, mais assurez-vous que le modèle que vous référencez correspond à la IndexFirstModel
page que vous avez créée, par exemple .
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() { }
}
}
Il n’y a pas de traitement spécial car il est seulement affiché, mais notez que nous l’avons ajouté en tant qu’attribut du nom de Authorize
la classe.
AuthenticationSchemes
L’argument est défini sur le nom de schéma spécifié dans Program.cs.
Cela garantit que vous ne pouvez afficher cette page que si vous vous connectez avec ce nom de schéma. Si vous visitez cette page sans vous connecter, vous serez redirigé vers la page de connexion.
Pages/IndexSecond.cshtml
Il s’agit de la deuxième page après la connexion.
@page
@model IndexSecondModel
@{
ViewData["Title"] = "Second page";
}
<div class="text-center">
<h1 class="display-4">Second Page</h1>
</div>
Pages/IndexSecond.cshtml.cs
Notez que le code est fondamentalement le même que celui de la première page de connexion, mais que le nom du schéma est différent.
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() { }
}
}
Création d’une page de connexion
Créez deux pages de connexion.
Pages/Compte/LoginFirst.cshtml.cs
Ajoutez l’attribut afin de pouvoir y accéder sans AllowAnonymous
vous connecter.
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
{
}
}
Créez une variable et un compte utilisateur factice pour recevoir les informations de connexion que vous avez saisies.
[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" },
};
}
Voici le processus de connexion.
<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");
}
La différence par rapport à une connexion unique réside dans le fait que chaque nom de schéma est spécifié.
L’emplacement que vous spécifiez est ClaimsIdentity
l’argument de et l’argument de HttpContext.SignInAsync
. Ici, vous pouvez spécifier le schéma avec lequel vous souhaitez vous connecter.
La déconnexion se présente également sous la forme de la spécification du nom du schéma.
<summary>ログアウト処理。</summary>
public async Task OnGetLogout()
{
// 認証クッキーをレスポンスから削除
await HttpContext.SignOutAsync("FirstAuth");
}
Pages/Compte/LoginFirst.cshtml
Le côté vue n’est pas différent d’une connexion unique. Veuillez faire correspondre le nom du modèle à référencer.
@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");
}
}
Pages/Compte/LoginSecond.cshtml.cs
Voici une autre logique de connexion. First
Second
C’est juste différent.
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");
}
}
}
Pages/Compte/LoginSecond.cshtml
Vue. First
C’est juste ça et Second
c’est différent.
@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");
}
}
Pages/Partagé/_Layout.cshtml
Ajoutez un lien de déconnexion pour chacun d’entre eux.
<!-- 中略 -->
<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>
<!-- 中略 -->
Programmes pour les projets MVC
Création d’un modèle de connexion
Cette fois-ci, les valeurs d’entrée des deux écrans de connexion sont les mêmes, nous allons donc les partager et n’en créer qu’un.
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; } = "";
}
}
Création d’un AccountController
Les deux processus de connexion sont AccountController
inclus dans , vous n’avez donc besoin d’ajouter qu’un seul contrôleur.
AllowAnonymous
Attribuez-le afin de pouvoir y accéder sans vous connecter.
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
{
}
}
Créez un compte d’utilisateur factice.
[AllowAnonymous]
public class AccountController : Controller
{
<summary>仮のユーザーデータベースとする。</summary>
private Dictionary<string, string> UserAccounts { get; set; } = new Dictionary<string, string>
{
{ "user1", "password1" },
{ "user2", "password2" },
};
}
Ajoutez une action pour afficher la page de la première connexion.
<summary>ログイン画面を表示します。</summary>
public IActionResult LoginFirst() => View();
Vous trouverez ci-dessous le code à traiter lors de la connexion.
<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");
}
La différence par rapport à une connexion unique réside dans le fait que chaque nom de schéma est spécifié.
L’emplacement que vous spécifiez est ClaimsIdentity
l’argument de et l’argument de HttpContext.SignInAsync
. Ici, vous pouvez spécifier le schéma avec lequel vous souhaitez vous connecter.
La déconnexion se présente également sous la forme de la spécification du nom du schéma.
<summary>ログアウト処理を実行します。</summary>
public async Task<IActionResult> LogoutFirst()
{
// 認証クッキーをレスポンスから削除
await HttpContext.SignOutAsync("FirstAuth");
// ログイン画面にリダイレクト
return RedirectToAction(nameof(LoginFirst));
}
J’ajouterai également le deuxième login. First
Il n’y a pas d’autre différence simplement en changeant la partie de 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));
}
// 中略
Création d’une vue (formulaire de connexion)
Créez deux vues chacune.
Il n’y a pas beaucoup de différence entre un seul login et un code, donc je vais poster le code tel quel.
Vues/Compte/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"); }
}
Vues/Compte/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"); }
}
Création d’écran après la connexion
HomeController
Créez deux nouveaux contrôleurs sans utiliser le contrôleur existant.
Il s’agit des contrôleurs auxquels vous pouvez accéder après vous être connecté.
Chaque écran est configuré pour être accessible différemment en fonction de l’écran auquel vous vous êtes connecté.
HomeFirstController.cs
Puisqu’il n’affiche que l’écran, il n’y a rien à ajouter au traitement.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace CookieAuthenticationMultipleMvc.Controllers
{
[Authorize(AuthenticationSchemes = "FirstAuth")]
public class HomeFirstController : Controller
{
public IActionResult Index() => View();
}
}
Au lieu de cela, il attache un attribut au contrôleur et AuthenticationSchemes
spécifie le nom du schéma en tant qu’argumentAuthorize
.
FirstAuth
Cela garantit que vous ne pouvez accéder à ce contrôleur que si vous vous authentifiez avec le schéma.
HomeSecondController.cs
Second
Créez le côté de la même manière.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace CookieAuthenticationMultipleMvc.Controllers
{
[Authorize(AuthenticationSchemes = "SecondAuth")]
public class HomeSecondController : Controller
{
public IActionResult Index() => View();
}
}
Vues/HomeFirst/Index.cshtml
Il n’y a rien de particulièrement difficile parce qu’il est juste affiché. Distinguez-les afin de voir de quelle page il s’agit.
@{
ViewData["Title"] = "First View";
}
<div class="text-center">
<h1 class="display-4">First View</h1>
</div>
Views/HomeSecond/Index.cshtml
Il suffit de le montrer ici aussi.
@{
ViewData["Title"] = "Second View";
}
<div class="text-center">
<h1 class="display-4">Second View</h1>
</div>
Vues/Partagé/_Layout.cshtml
Ajoutez un lien de déconnexion pour chacun d’entre eux.
<!-- 中略 -->
<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>
<!-- 中略 -->
Confirmation de fonctionnement
Veuillez l’exécuter pour voir comment cela fonctionne. Je suis sûr que vous avez déjà vu le fonctionnement de la connexion unique, donc Je pense que c’est une bonne idée de vérifier ce qui se passe lorsque vous accédez à chaque écran lorsque vous conservez le statut de connexion dans le schéma suivant.
- Ni le premier ni le deuxième ne sont connectés
- Le premier est connecté et le second n’est pas connecté
- Le premier n’est pas connecté, le second est connecté
- Le premier et le deuxième sont tous deux connectés