溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

在ASP.NET Core中使用Cookie中間件的方法

發(fā)布時間:2020-08-28 14:09:15 來源:億速云 閱讀:145 作者:小新 欄目:編程語言

小編給大家分享一下在ASP.NET Core中使用Cookie中間件的方法,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

在 http:// ASP.NET Core 中使用Cookie中間件

ASP.NET Core 提供了Cookie中間件來序列化用戶主題到一個加密的Cookie中并且在后來的請求中校驗這個Cookie,再現(xiàn)用戶并且分配到HttpContext對象的User屬性中。如果你想提供自己的登錄方式和用戶數(shù)據(jù)你可以使用Cookie中間件來實現(xiàn)獨立的功能。

添加和配置

第一步是增加Cookie中間件到你的應(yīng)用中。首先使用nuget增加Microsoft.AspNetCore.Authentication.Cookies 程序包。然后添加下面的幾行代碼到Startup.cs文件的Configure方法中,且要在app.UseMvc()之前。

app.UseCookieAuthentication(new CookieAuthenticationOptions()
 {
  AuthenticationScheme = "MyCookieMiddlewareInstance",
  LoginPath = new PathString("/Account/Unauthorized/"),
  AccessDeniedPath = new PathString("/Account/Forbidden/"),
  AutomaticAuthenticate = true,
  AutomaticChallenge = true
 });

上面的代碼片段配置了一下幾個選項;

  1. 認證方案:這是一個已知中間件的值,當(dāng)有多個實例的中間件如果你想限制授權(quán)到一個實例時這個選項將會起作用。

  2. 登錄路徑:這是當(dāng)用戶試圖訪問資源但未經(jīng)過身份驗證時,程序?qū)⒄埱笾囟ㄏ虻竭@個相對路徑。

  3. 禁止訪問路徑:當(dāng)用戶試圖訪問資源時,但未通過該資源的任何授權(quán)策略,請求將被重定向到這個相對路徑。

  4. 自動認證:這個標(biāo)志表明中間件應(yīng)該會在每個請求上進行驗證和重建他創(chuàng)建的序列化主體。

  5. 自動挑戰(zhàn):這個標(biāo)志標(biāo)明當(dāng)中間件認證失敗時應(yīng)該重定向瀏覽器到登錄路徑或者禁止訪問路徑。

其他選項包括設(shè)置中間件所創(chuàng)建的聲明的發(fā)行者,中間件存儲的cookie名稱,Cookie的域和cookie上的各種安全屬性。默認情況下Cookie中間件將使用適當(dāng)?shù)陌踩x項,設(shè)置HTTPONLY避免cookie在客戶端被JavaScript操作。當(dāng)請求方式為HTTPS時限制Cookie的HTTPS操作。

創(chuàng)建Cookie

創(chuàng)建Cookie保存自己的信息,必須要初始化一個ClaimsPrincipal(類型)來序列化和保存你想保存的用戶信息到Cookie中。每一次的方法調(diào)用都會在你的Controller(控制器)中有一個合適的ClaimsPrincipal對象。

復(fù)制代碼 代碼如下:

await HttpContext.Authentication.SignInAsync("MyCookieMiddlewareInstance", principal);

上面的代碼將會創(chuàng)建一個加密的Cookie并且增加到當(dāng)前的請求響應(yīng)中。AuthenticationScheme明確規(guī)定在配置期間

退出

退出當(dāng)前用戶的登錄,刪除登錄的cookie信息,可以在控制器中調(diào)用下面的方法。

復(fù)制代碼 代碼如下:

await HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");

響應(yīng)后端的變化

警告

一旦cookie創(chuàng)建就會成為身份單一認證的來源,即使在后臺系統(tǒng)已經(jīng)不可用,中間件也是不知道的,并且始終保持登錄直到cookie失效。

Cookie認證中間件在他的選項類中提供了一系列的事件,其中 ValidateAsync() 事件可以用來中斷和重寫cookie認證的驗證方法。

考慮到后臺用戶的數(shù)據(jù)庫中可能會有‘最后的修改時間'這一列,為了在數(shù)據(jù)庫修改之后你可以廢止當(dāng)前的Cookie,第一當(dāng)創(chuàng)建這個Cookie時添加一個最后修改的聲明并包含當(dāng)前的值,當(dāng)數(shù)據(jù)庫中的數(shù)據(jù)改變時,這個值也同時更新。

實現(xiàn)一個ValidateAsync()的事件重寫你必須寫一個具有如下簽名的方法。

Task ValidateAsync(CookieValidatePrincipalContext context);

ASP.NET Core 認證在SecurityStampValidator中實現(xiàn)了這個驗證。下面是一個類似的例子:

public static class LastChangedValidator
 {
  public static async Task ValidateAsync(CookieValidatePrincipalContext context)
  {
   // Pull database from registered DI services.
   var userRepository = context.HttpContext.RequestServices.GetRequiredService<IUserRepository>();
   var userPrincipal = context.Principal;

   // Look for the last changed claim.
   string lastChanged;
   lastChanged = (from c in userPrincipal.Claims
       where c.Type == "LastUpdated"
       select c.Value).FirstOrDefault();

   if (string.IsNullOrEmpty(lastChanged) ||
    !userRepository.ValidateLastChanged(userPrincipal, lastChanged))
   {
    context.RejectPrincipal();
    await context.HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");
   }
  }
 }

這些要在Cookie中間件配置時進行注冊

app.UseCookieAuthentication(options =>
 {
  options.Events = new CookieAuthenticationEvents
  {
   // Set other options
   OnValidatePrincipal = LastChangedValidator.ValidateAsync
  };
 });

如果你想非破壞性的更新用戶主體,例如,name更新了,要想以不影響安全的方式你可以調(diào)用 context.ReplacePrincipal() 并且設(shè)置 context.ShouldRenew 為 true 。

控制Cookie選項

CookieAuthenticationOptions配備了各種各樣的配置選項是你能夠很好的調(diào)節(jié)創(chuàng)建的Cookie。

  1. ClaimsIssuer - 被用來在任何中間件創(chuàng)建的屬性之上。(看不懂)

  2. CookieDomain - 如果cookie domain被設(shè)置為 ** . http:// contoso.com ** 那么 contoso.com, http://www. contoso.com,staging.contoso.com 等等類似這樣的域名也會被允許。

  3. CookieHttpOnly - 這個標(biāo)志指示這個 cookie 只會被服務(wù)端訪問。默認值是true,修改這個屬性將會開放你的應(yīng)用造成 Cookie 盜竊,造成跨站腳本的bug。

  4. CookiePath - 這個可以用來隔離運行在同一個 host 下的應(yīng)用。如果你有一個應(yīng)用運行在 /app1 上,并且想限制 cookie 限制僅僅被發(fā)送給自己,那么你應(yīng)該設(shè)置 CookiePath 屬性為 /app1 ;Cookie將會明白只適用于道 /app1 或者他下面的請求。

  5. ExpireTimeSpan - 這個 TimeSpan 時間段之后 Cookie 將會過期。

  6. SlidingExpiration - 這個標(biāo)志標(biāo)記了如果超過了過期時間的一半后被訪問那么Cookie將會被重置。新的過期時間將會后移到當(dāng)前時間加上ExpireTimespan之后。當(dāng)調(diào)用 SignInAsync 時可以通過 ** AuthenticationProperties ** 設(shè)置絕對的過期時間。通過限制驗證cookie有效的時間,絕對期滿可以提高應(yīng)用程序的安全性。

持續(xù)性Cookie和絕對過期時間

您可能希望通過瀏覽器會話使cookie過期。也許你也想通過絕對過期時間和認證來結(jié)束cookie,那么你可以在登錄認證和創(chuàng)建Cookie時使用HttpContext.Authentication.SignInAsync方法中的AuthenticationProperties參數(shù)類實現(xiàn)。AuthenticationProperties類在Microsoft.AspNetCore.Http.Authentication命名空間中。

例如

await HttpContext.Authentication.SignInAsync(
  "MyCookieMiddlewareInstance",
  principal,
  new AuthenticationProperties
  {
   IsPersistent = true
  });

這個代碼片段將會實現(xiàn)創(chuàng)建一個認證和相應(yīng)的Cookie來實現(xiàn)即時瀏覽器關(guān)閉Cookie也能繼續(xù)保留。任何在cookie屬性中的過期時間的設(shè)置都將會保存下來。如果瀏覽器關(guān)閉時Cookie也過期了那么在重新啟動瀏覽器是Cookie將會別清理。

await HttpContext.Authentication.SignInAsync(
  "MyCookieMiddlewareInstance",
  principal,
  new AuthenticationProperties
  {
   ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
  });

這段代碼將創(chuàng)建一個身份認證和相應(yīng)的cookie且將持續(xù)20分鐘。 任何在Cookie options中配置的動態(tài)選項都會被忽略。 ExpiresUtc 和 IsPersistent 這兩個屬性是相互獨立的。

其實上面bb了那么多,都沒用! 不如來個demo

// 1. 在Startup.cs的Configure方法中加上
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
 AuthenticationScheme = "UserAuth",  // Cookie 驗證方案名稱,在寫cookie時會用到。
 AutomaticAuthenticate = true,     // 是否自動啟用驗證,如果不啟用,則即便客服端傳輸了Cookie信息,服務(wù)端也不會主動解析。除了明確配置了 [Authorize(ActiveAuthenticationSchemes = "上面的方案名")] 屬性的地方,才會解析,此功能一般用在需要在同一應(yīng)用中啟用多種驗證方案的時候。比如分Area.
 LoginPath = "/User/Index"     // 登錄頁
});

// 2. 新建UserController
// 3. 創(chuàng)建一個測試登錄的方法(這里為了方便測是我用的是get方法,方便傳參請求)
public IActionResult Login(int userId, string userName)
{
 WriteUser(userId, userName);
 return Content("Write");
}

private async void WriteUser(int userId, string userName)
{
 var identity = new ClaimsIdentity("Forms");  // 指定身份認證類型
 identity.AddClaim(new Claim(ClaimTypes.Sid, userId.ToString()));  // 用戶Id
 identity.AddClaim(new Claim(ClaimTypes.Name, userName));       // 用戶名稱
 var principal = new ClaimsPrincipal(identity);
 await HttpContext.Authentication.SignInAsync("UserAuth", principal, new AuthenticationProperties { IsPersistent = true , ExpiresUtc = DateTime.UtcNow.AddMinutes(20) }); //過期時間20分鐘
}

// 4. 創(chuàng)建一個退出登錄的方法
public async Task<ActionResult> Logout()
{
 await HttpContext.Authentication.SignOutAsync("UserAuth"); // Startup.cs中配置的驗證方案名
 return RedirectToAction("User", "Index");
}

// 5. 創(chuàng)建一個獲取cookie用戶信息的方法方便調(diào)用
private int GetUserId()
{ 
 //var userName = User.Identity.Name; //獲取登錄時存儲的用戶名稱
 var userId = User.FindFirst(ClaimTypes.Sid).Value; // 獲取登錄時存儲的Id
 if (string.IsNullOrEmpty(userId))
 {
  return 0;
 }
 else
 {
  return int.Parse(userId);
 }
}
// 或者寫一個測試Action
public JsonResult CheckLogin()
{
 var userName = User.Identity.Name; //獲取登錄時存儲的用戶名稱
 var userId = User.FindFirst(ClaimTypes.Sid).Value; // 獲取登錄時存儲的Id
 return Json({UserId:userId,UserName:userName});
}

// 6. 以上是加密的方式如果直接寫好像也是可以的
HttpContext.Response.Cookies.Append("Key", "Value");

看完了這篇文章,相信你對在ASP.NET Core中使用Cookie中間件的方法有了一定的了解,想了解更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI