最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在ASP.NET Core中實現(xiàn)Cookie身份驗證的方法步驟

 更新時間:2026年03月15日 14:05:03   作者:hefeng_aspnet  
ASP.NET Core Identity是一個功能齊全的網(wǎng)站安全框架,它提供了許多特性,例如外部登錄和JWT支持,然而,有時您需要的是一種簡單易用且能讓您完全掌控數(shù)據(jù)存儲和帳戶管理等各個方面的解決方案,本文將介紹 Cookie 身份驗證的概念以及如何配置它來保護您的網(wǎng)站

如果您一直在使用 ASP.NET Core,那么您可能已經(jīng)了解 ASP.NET Core Identity。ASP.NET Core Identity 是一個功能齊全的網(wǎng)站安全框架,它提供了許多特性,例如外部登錄和 JSON Web Tokens (JWT) 支持。然而,有時您需要的是一種簡單易用且能讓您完全掌控數(shù)據(jù)存儲和帳戶管理等各個方面的解決方案。這時,ASP.NET Core 的 Cookie 身份驗證就派上用場了。本文將介紹 Cookie 身份驗證的概念以及如何配置它來保護您的網(wǎng)站。

一些背景信息

在詳細介紹 cookie 身份驗證的配置和實現(xiàn)細節(jié)之前,我忍不住要強調一下 ASP.NET classic 和 ASP.NET Core 在這方面的相似之處。

ASP.NET 1.x 版本推出時,主要有兩種身份驗證方式:基于 Windows 的身份驗證和表單身份驗證。表單身份驗證也稱為 Cookie 身份驗證,因為它基于 Cookie 形式的身份驗證票據(jù)工作。表單身份驗證本身不進行任何用戶管理。它只是根據(jù)是否存在特定的 Cookie 來檢查傳入的請求是否已通過身份驗證,并據(jù)此允許或拒絕最終用戶的訪問。用戶帳戶管理是開發(fā)人員的責任,需要編寫自定義代碼來實現(xiàn)。這種簡單的方法雖然提供了對底層數(shù)據(jù)存儲和用戶管理的完全控制,但另一方面也要求您自行編寫所有邏輯。

在 ASP.NET 2.0 中,表單身份驗證新增了成員資格、角色和配置文件提供程序。成員資格框架負責用戶和角色的管理。這種方法節(jié)省了大量編寫必要代碼的時間。但它也有自身的局限性,例如數(shù)據(jù)庫結構較為僵化,以及用戶管理 API 集較為固定。

后來,微軟發(fā)布了 ASP.NET Identity——一個能夠滿足現(xiàn)代網(wǎng)站安全需求(例如外部登錄)的新框架。

在 ASP.NET Core 中,我們有兩種類似的選項來實現(xiàn)網(wǎng)站安全:ASP.NET Core Identity 或簡單的 Cookie 身份驗證。

現(xiàn)在你已經(jīng)對 cookie 身份驗證有了一些了解,讓我們開始吧。

首先創(chuàng)建一個新的 ASP.NET Core Web 應用程序,然后按照以下步驟操作。

創(chuàng)建數(shù)據(jù)庫表和 DbContext

當我們決定在 ASP.NET Core 網(wǎng)站中使用 Cookie 身份驗證時,數(shù)據(jù)存儲和數(shù)據(jù)結構由我們自行負責。例如,我們將在 SQL Server 數(shù)據(jù)庫中創(chuàng)建一個簡單的表,但您可以使用任何您選擇的數(shù)據(jù)存儲方式(例如,NoSQL 數(shù)據(jù)庫)。

創(chuàng)建具有以下結構的數(shù)據(jù)庫表:

如您所見,我們創(chuàng)建了一個名為 MyAppUsers 的表來存儲用戶信息。該表結構簡單,包含四列:Id、UserName、Password 和 Roles。為了保持簡潔,我們存儲的所有信息均未加密。此外,角色信息也存儲在同一個表中,而不是單獨創(chuàng)建一個表。

現(xiàn)在在項目根目錄下添加 DataAccess 文件夾,并添加 Entity 和 DbContext 類,如下所示:

[Table("MyAppUsers")]
public class MyAppUser
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public string Roles { get; set; }
}

MyAppUser 類對應于我們剛剛創(chuàng)建的 MyAppUsers 表,并具有相應的屬性。

public class MyAppDbContext:DbContext
{
? ? public MyAppDbContext(DbContextOptions<MyAppDbContext>?
options) : base(options)
? ? {
? ? }
? ? public DbSet<MyAppUser> MyAppUsers { get; set; }
}

MyAppDbContext 類繼承自 DbContext,并包含 MyAppUsers DbSet。

配置 Cookie 身份驗證

好的。現(xiàn)在我們已經(jīng)準備好了 DbContext,接下來讓我們?yōu)?Web 應用程序啟用 Cookie 身份驗證。打開 Startup 類并按如下所示修改 ConfigureServices() 方法:

public void ConfigureServices(IServiceCollection services)
{
? ? services.AddMvc();
? ? services.AddEntityFrameworkSqlServer();
? ? services.AddDbContext<MyAppDbContext>(options =>
?options.UseSqlServer("data source=.;initial?
catalog=northwind;integrated security=true;
multipleactiveresultsets=true"));
? ? services.AddAuthentication
(CookieAuthenticationDefaults.AuthenticationScheme)
? ? ? ? .AddCookie();
}

除了以粗體字標記的代碼外,ConfigureServices() 方法對您來說應該很熟悉。AddAuthentication() 和 AddCookie() 方法會將 Cookie 身份驗證服務注冊到框架中。請注意,AddAuthentication() 方法接受一個字符串參數(shù),用于指定安全方案的名稱。該值可以是開發(fā)人員定義的任何值,也可以使用 CookieAuthenticationDefaults 類的 AuthenticationScheme 屬性指定的默認值。

此外,請務必根據(jù)您的配置更改 AddDbContext() 調用中的數(shù)據(jù)庫連接字符串。您也可以從配置文件中獲取該字符串。

接下來,修改 Configure() 方法以使用 cookie 身份驗證中間件:

public void Configure(IApplicationBuilder app,?
IHostingEnvironment env)
{
? ? app.UseDeveloperExceptionPage();
? ? app.UseAuthentication();
? ? app.UseMvcWithDefaultRoute();
}

我們剛剛完成了網(wǎng)站的 cookie 身份驗證配置。

創(chuàng)建 RegisterViewModel 和 LoginViewModel 類

我們需要兩個視圖模型——RegisterViewModel 和 LoginViewModel——類如下所示:

public class RegisterViewModel
{
    [Required]
    public string UserName { get; set; }
    [Required]
    public string Password { get; set; }
    [Required]
    [Compare("Password")]
    public string ConfirmPassword { get; set; }
}

RegisterViewModel 類封裝了在注冊視圖(稍后討論)中輸入的注冊詳細信息。

public class LoginViewModel
{
    [Required]
    public string UserName { get; set; }
    [Required]
    public string Password { get; set; }
    [Required]
    public bool RememberMe { get; set; }
}

LoginViewModel 類封裝了用戶在登錄視圖中輸入的登錄信息。請注意 RememberMe 屬性,它指示是否應在關閉瀏覽器會話后保留用戶的登錄狀態(tài)。 

創(chuàng)建賬戶控制器

視圖模型準備就緒后,在 Controllers 文件夾下添加 AccountController 類。AccountController 將包含五個操作:

  • Register() - Register() 操作的 GET 和 POST 版本負責創(chuàng)建新的用戶帳戶。
  • Login() - Login() 操作的 GET 和 POST 版本負責將用戶登錄到系統(tǒng)中。系統(tǒng)會在此過程中向用戶頒發(fā)身份驗證 cookie。
  • Logout() - Logout() 的 POST 版本會刪除之前頒發(fā)的身份驗證 cookie。

讓我們逐一分析這些方法。

上述操作需要在構造函數(shù)中注入 MyAppDbContext。因此,首先將以下代碼添加到 AccountController 中:

private MyAppDbContext db;?
public AccountController(MyAppDbContext db)?
{?
? ? this.db = db;?
}

創(chuàng)建用戶帳戶

以下代碼展示了 Register() 操作的兩種版本:

public IActionResult Register()
{
? ? return View();
}
[HttpPost]
public IActionResult Register(RegisterViewModel model)
{
? ? if (ModelState.IsValid)
? ? {
? ? ? ? MyAppUser user = new MyAppUser();
? ? ? ? user.UserName = model.UserName;
? ? ? ? user.Password = model.Password;
? ? ? ? user.Roles = "Manager,Administrator";
? ? ? ? db.MyAppUsers.Add(user);
? ? ? ? db.SaveChanges();
? ? ? ? ViewData["message"] = "User created successfully!";
? ? }
? ? return View();
}

POST 版本的 Register() 方法通過模型綁定接收 RegisterViewModel 對象。在該方法內部,我們將值從 RegisterViewModel 傳遞到 MyAppUser,然后將新用戶添加到 MyAppUsers 數(shù)據(jù)庫集合中。請注意,我們還將 Roles 屬性設置為 Manager 和 Administrator。在更實際的場景中,通常會有一個單獨的頁面用于為用戶分配角色。調用 SaveChanges() 方法會在我們最初創(chuàng)建的 MyAppUsers 表中創(chuàng)建用戶帳戶。

我們還設置了一條成功消息到 ViewData 中,該消息可以在注冊視圖中顯示。請注意,為了簡化起見,我們沒有對創(chuàng)建的用戶帳戶添加任何驗證和檢查。

登錄應用程序

下面展示了 Login() 函數(shù)的兩個版本:

public IActionResult Login(string returnUrl)
{
? ? return View();
}
[HttpPost]
public IActionResult Login(LoginViewModel model,
string returnUrl)
{
? ? bool isUservalid = false;
? ? MyAppUser user = db.MyAppUsers.Where(usr =>?
usr.UserName == model.UserName &&?
usr.Password == model.Password).SingleOrDefault();
? ? if(user!=null)
? ? {
? ? ? ? isUservalid = true;
? ? }
? ? if(ModelState.IsValid && isUservalid)
? ? {
? ? ? ? var claims = new List<Claim>();
? ? ? ? claims.Add(new Claim(ClaimTypes.Name, user.UserName));
? ? ? ? string[] roles = user.Roles.Split(",");
? ? ? ? foreach (string role in roles)
? ? ? ? {
? ? ? ? ? ? claims.Add(new Claim(ClaimTypes.Role, role));
? ? ? ? }
? ? ? ? var identity = new ClaimsIdentity(
? ? ? ? ? ? claims, CookieAuthenticationDefaults.
AuthenticationScheme);
? ? ? ? var principal = new ClaimsPrincipal(identity);
? ? ? ? var props = new AuthenticationProperties();
? ? ? ? props.IsPersistent = model.RememberMe;
? ? ? ? HttpContext.SignInAsync(
? ? ? ? ? ? CookieAuthenticationDefaults.
AuthenticationScheme,
? ? ? ? ? ? principal, props).Wait();
? ? ? ? return RedirectToAction("Index", "Home");
? ? }
? ? else
? ? {
? ? ? ? ViewData["message"] = "Invalid UserName?
or Password!";
? ? }
? ? return View();
}

Login() 的 POST 版本對我們來說很重要,因為正是在這里向用戶頒發(fā)身份驗證 cookie。

代碼首先判斷用戶名和密碼是否有效。這是通過檢查是否存在與給定用戶名和密碼匹配的 MyAppUser 實體來實現(xiàn)的。如果存在匹配的用戶名和密碼,則將 isUserValid 布爾變量賦值為 true 或 false。

如果用戶有效,則會創(chuàng)建四個對象:

  • 索賠對象列表
  • ClaimsIdentity 對象
  • ClaimsPrincipal 對象
  • 身份驗證屬性對象

聲明對象列表保存了用戶的所有聲明。我們添加的第一個聲明對象類型為 Name,表示用戶的用戶名。此聲明是必需的,以便 HttpContext.User.Identity.Name 屬性返回當前用戶的用戶名。

然后,我們?yōu)橛脩籼砑右幌盗薪巧?。這是通過拆分 MyAppUser 的 Roles 屬性,然后添加 Role 類型的 Claim 對象來實現(xiàn)的。這樣做是為了確保 HttpContext.User.IsInRole() 方法能夠按預期工作。

稍后在 HomeController 中,我們將使用 HttpContext.User.Identity.Name 和 HttpContext.User.IsInRole()。

然后,代碼通過傳遞 Claim 對象列表和身份驗證方案名稱來創(chuàng)建 ClaimsIdentity 對象。

然后,代碼通過在構造函數(shù)中傳遞 ClaimsIdentity 來創(chuàng)建一個 ClaimsPrincipal 對象。

然后,代碼會創(chuàng)建一個 AuthenticationProperties 對象。AuthenticationProperties 對象保存著當前身份驗證會話使用的某些屬性的值,例如 IsPersistent。

最后,調用 HttpContext 的 SignInAsync() 方法向用戶頒發(fā)身份驗證 cookie。SignInAsync() 方法接受身份驗證方案名稱、ClaimsPrincipal 和 AuthenticationProperties 這三個參數(shù)。

用戶成功登錄后,響應將重定向到 HomeController 的 Index() 操作。您也可以使用 Login() 操作的 returnUrl 參數(shù)來實現(xiàn)重定向。

如果用戶無效,則會相應地設置 ViewData 消息。

從應用程序中注銷

下面顯示的是移除身份驗證 cookie 的 Logout() 操作:

[HttpPost] 
public IActionResult Logout() 
{  
HttpContext.SignOutAsync( CookieAuthenticationDefaults.AuthenticationScheme);  
return RedirectToAction("Login", "Account"); 
}

Logout() 操作會調用 HttpContext 的 SignOutAsync() 方法,并傳入身份驗證方案名稱。此方法會移除身份驗證 cookie。之后,用戶將被重定向到登錄頁面。

創(chuàng)建注冊和登錄視圖

好的,目前為止一切順利?,F(xiàn)在我們來創(chuàng)建視圖。在“視圖”>“帳戶”文件夾下添加兩個視圖:Register.cshtml 和 Login.cshtml。

這是瀏覽器中“注冊”頁面的顯示效果:

下面給出的是創(chuàng)建登錄視圖的標記:

@model SimpleCookieAuth.ViewModels.RegisterViewModel
<h1>Register</h1>
<form asp-controller="Account" asp-action="Register"?
method="post">
? ? <table>
? ? ? ? <tr>
? ? ? ? ? ? <td><label asp-for="UserName"></label></td>
? ? ? ? ? ? <td><input asp-for="UserName" /></td>
? ? ? ? </tr>
? ? ? ? <tr>
? ? ? ? ? ? <td><label asp-for="Password"></label></td>
? ? ? ? ? ? <td><input asp-for="Password"?
type="password" /></td>
? ? ? ? </tr>
? ? ? ? <tr>
? ? ? ? ? ? <td><label asp-for="ConfirmPassword"></label></td>
? ? ? ? ? ? <td><input asp-for="ConfirmPassword"?
type="password"/></td>
? ? ? ? </tr>
? ? ? ? <tr>
? ? ? ? ? ? <td colspan="2">
? ? ? ? ? ? ? ? <input type="submit"
? ? ? ? ? ? ? ? ? ? ? ?value="Register" />
? ? ? ? ? ? </td>
? ? ? ? </tr>
? ? </table>
? ? <div asp-validation-summary="All"></div>
? ? <br />
? ? <div>@ViewData["message"]</div>
</form>

表單標簽助手會將表單提交到 AccountController 的 Login() 操作。登錄頁面包含用于輸入用戶名和密碼的文本框,以及一個用于指示是否記住登錄狀態(tài)的復選框。

至此,注冊和登錄界面已完成。

創(chuàng)建 HomeController 和 Index 視圖

現(xiàn)在添加 HomeController 并按如下所示修改 Index() 操作:

[Authorize]
public IActionResult Index()
{
? ? string userName = HttpContext.User.Identity.Name;
? ? if(HttpContext.User.IsInRole("Administrator"))
? ? {
? ? ? ? ViewData["adminMessage"] = "You are an Administrator!";
? ? }
? ? if (HttpContext.User.IsInRole("Manager"))
? ? {
? ? ? ? ViewData["managerMessage"] = "You are a Manager!";
? ? }
? ? ViewData["username"] = userName;
? ? return View();
}

請注意以粗體字標記的代碼。Index() 操作帶有 [Authorize] 屬性,表明這是一個安全操作,只能由已認證的用戶調用。

HttpContext.User.Identity.Name 屬性返回當前用戶的名稱。請記住,我們之前在 Login() 操作中添加了一個類型為 Name 的 Claim 對象,以使該屬性能夠按預期工作。

如果當前用戶屬于指定的角色,則 HttpContext.User.IsInRole() 方法返回 true。請記住,我們之前在 Login() 操作中添加了 Role 類型的 Claim 對象,以使此方法按預期工作。

索引視圖的示例運行會產(chǎn)生以下輸出:

下面顯示的是索引視圖背后的標記:

<h1>Welcome @ViewData["username"]!</h1>
<h2>@ViewData["adminMessage"]</h2>
<h2>@ViewData["managerMessage"]</h2>
<form asp-controller="Account" asp-action="Logout"?
method="post">
<input type="submit" value="Logout" />
</form>

這段標記代碼只是簡單地輸出之前添加的各種 ViewData 條目,并在底部渲染“注銷”按鈕。點擊“注銷”按鈕會觸發(fā) AccountController 的 Logout() 操作。

示例應用程序到此完成。運行該應用程序。您會注意到,盡管您嘗試訪問 HomeController 的 Index() 操作,但系統(tǒng)卻跳轉到了登錄頁面。您還會看到 RetrnUrl 查詢字符串參數(shù)指向 Web 應用程序的根目錄。使用登錄頁面底部的“創(chuàng)建用戶”鏈接進入注冊視圖。創(chuàng)建一個新的用戶帳戶并嘗試使用該帳戶登錄。同時,檢查“記住我”復選框是否正常工作。

以上就是在ASP.NET Core中實現(xiàn)Cookie身份驗證的方法步驟的詳細內容,更多關于ASP.NET Core實現(xiàn)Cookie身份驗證的資料請關注腳本之家其它相關文章!

相關文章

最新評論

赞皇县| 普兰县| 都江堰市| 六安市| 封丘县| 龙口市| 石城县| 永春县| 莱芜市| 福建省| 临颍县| 托克托县| 布尔津县| 阿巴嘎旗| 连城县| 漠河县| 白沙| 崇义县| 吴忠市| 林州市| 石泉县| 兴隆县| 射洪县| 新宾| 石柱| 吴桥县| 方城县| 从江县| 晋江市| 黔西县| 兴城市| 淳化县| 唐山市| 舒兰市| 东乌珠穆沁旗| 梨树县| 德化县| 湘潭县| 苍溪县| 滨海县| 定远县|