สร้างหน้าจอเข้าสู่ระบบหลายหน้าจอและจํากัดหน้าที่สามารถเข้าถึงได้โดยหน้าจอที่คุณเข้าสู่ระบบ
สภาพแวดล้อมในการทํางาน
- วิชวลสตูดิโอ
-
- ชุมชน Visual Studio 2022
- ASP.NET Core (MVC, หน้ามีดโกน)
- 6.0
ทีแรก
ส่วนนี้อธิบายวิธีเตรียมหน้าจอเข้าสู่ระบบหลายหน้าจอในแอปพลิเคชันเดียว และแยกหน้าที่แต่ละหน้าจอเข้าสู่ระบบสามารถเข้าถึงได้ วิธีการสร้างหน้าจอเข้าสู่ระบบเดียวอธิบายไว้ใน "การสร้างกลไกการเข้าสู่ระบบโดยใช้การตรวจสอบคุกกี้และการสร้างกลไกที่จะเปลี่ยนเส้นทางหากคุณไม่ได้รับการตรวจสอบสิทธิ์" และเนื้อหานี้อธิบายบนสมมติฐานว่าคุณมีความรู้ในการสร้างหน้าจอเข้าสู่ระบบเดียว ดังนั้นกระบวนการเช่นเดียวกับหน้าจอเข้าสู่ระบบเดียวจึงเป็นเพียงคําอธิบายง่ายๆ
สร้างโครงการ
ฉันกําลังสร้างตัวอย่าง Razor Pages และ MVC แต่ไม่เป็นไรที่จะสร้างเฉพาะโปรเจ็กต์ที่คุณต้องการใช้
แก้ไขโปรแกรม.cs (หน้ามีดโกน, MVC ทั่วไป)
คราวนี้เราจะใช้วิธีการแยกหน้าที่สามารถเข้าถึงได้โดยหน้าเข้าสู่ระบบโดยใช้ชื่อ "สคีมา"
ขั้นแรก ให้เพิ่มเนมสเปซที่ด้านบนของโค้ด
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
ต่อไปนี้เป็นตัวสร้าง รหัสที่จะเพิ่มลงในบริการ
// === 省略 ===
// 「Razor Pages」のコード
// builder.Services.AddRazorPages();
// 「MVC」のコード
// builder.Services.AddControllersWithViews();
// ※ここから追加
// Cookie による認証スキームを追加する
builder.Services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie("FirstAuth", option =>
{
option.LoginPath = "/Account/LoginFirst";
})
.AddCookie("SecondAuth", option =>
{
option.LoginPath = "/Account/LoginSecond";
});
builder.Services.AddAuthorization(options =>
{
// 認証属性を設定していない画面は FirstAuth スキーマの認証が必要となる
options.FallbackPolicy = new AuthorizationPolicyBuilder("FirstAuth")
.RequireAuthenticatedUser()
.Build();
});
// ※ここまで追加
var app = builder.Build();
// === 省略 ===
ความแตกต่างจากครั้งที่แล้วคือคุกกี้ถูกเพิ่มเป็นสอง
AddCookie
อาร์กิวเมนต์แรกของแต่ละรายการประกอบด้วยชื่อสคีมาที่ระบุการเข้าสู่ระบบ ชื่อนี้สามารถเป็นอะไรก็ได้ตราบใดที่เป็นชื่ออื่น
อาร์กิวเมนต์ที่สองคือ URL ของหน้าเข้าสู่ระบบที่จะถูกเปลี่ยนเส้นทางเมื่อมีการเข้าถึงการเข้าสู่ระบบโดยไม่ต้องเข้าสู่ระบบ
อย่างไรก็ตาม ถ้าคุณไม่ระบุชื่อสคีมา มันจะ CookieAuthenticationDefaults.AuthenticationScheme
เหมือนกับ .
FallbackPolicy
นอกจากนี้ยังระบุสคีมาเป็นการตั้งค่าสําหรับFirstAuth
ด้วยเหตุนี้ จึงจําเป็นต้องเข้าถึงFirstAuth
การรับรองความถูกต้องแบบไม่มีใครแตะต้องIndex.cshtml
หรือPrivacy.cshtml
สคีมานี้
รหัสสําหรับแอปต่อไปนี้เหมือนกับการเข้าสู่ระบบครั้งเดียว
// === 省略 ===
app.UseRouting();
app.UseAuthentication(); // [追加] 認証
app.UseAuthorization(); // 認可
// 「Razor Pages」のコード
// app.MapRazorPages();
// 「MVC」のコード
// app.MapControllerRoute(
// name: "default",
// pattern: "{controller=Home}/{action=Index}/{id?}");
// === 省略 ===
โปรแกรมสําหรับโครงการ 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
อาร์กิวเมนต์ถูกตั้งค่าเป็นชื่อ Schema ที่ระบุใน Program.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
สร้างคอนโทรลเลอร์ใหม่สองตัวโดยไม่ต้องใช้คอนโทรลเลอร์ที่มีอยู่
นี่คือตัวควบคุมที่คุณสามารถเข้าถึงได้หลังจากเข้าสู่ระบบ
แต่ละหน้าจอถูกตั้งค่าให้สามารถเข้าถึงได้แตกต่างกันไปขึ้นอยู่กับหน้าจอที่คุณเข้าสู่ระบบ
หน้าหลัก FirstController.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>
<!-- 中略 -->
การยืนยันการดําเนินการ
โปรดเรียกใช้เพื่อดูว่ามันทํางานอย่างไร ฉันแน่ใจว่าคุณเคยเห็นงานเข้าสู่ระบบเดียวแล้ว ดังนั้น ฉันคิดว่าเป็นความคิดที่ดีที่จะตรวจสอบว่าจะเกิดอะไรขึ้นเมื่อคุณเข้าถึงแต่ละหน้าจอเมื่อคุณรักษาสถานะการเข้าสู่ระบบในรูปแบบต่อไปนี้
- ไม่มีการเข้าสู่ระบบครั้งแรกและครั้งที่สอง
- ครั้งแรกเข้าสู่ระบบและที่สองไม่ได้เข้าสู่ระบบ
- ครั้งแรกไม่ได้เข้าสู่ระบบ ที่สองเข้าสู่ระบบ
- เข้าสู่ระบบทั้งที่หนึ่งและสอง