如何在ASP.NET Core中使用Cookie中介軟體的詳細介紹

來源:互聯網
上載者:User
本篇文章主要介紹了詳解在ASP.NET Core 中使用Cookie中介軟體,具有一定的參考價值,感興趣的小夥伴們可以參考一下

在 http:// ASP.NET Core 中使用Cookie中介軟體

ASP.NET Core 提供了Cookie中介軟體來序列化使用者主題到一個加密的Cookie中並且在後來的請求中校正這個Cookie,再現使用者並且分配到HttpContext對象的User屬性中。如果你想提供自己的登入方式和使用者資料你可以使用Cookie中介軟體來實現獨立的功能。

添加和配置

第一步是增加Cookie中介軟體到你的應用中。首先使用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. 認證方案:這是一個已知中介軟體的值,當有多個執行個體的中介軟體如果你想限制授權到一個執行個體時這個選項將會起作用。

  2. 登入路徑:這是當使用者試圖訪問資源但未經過身分識別驗證時,程式將會將請求重新導向到這個相對路徑。

  3. 禁止訪問路徑:當使用者試圖訪問資源時,但未通過該資源的任何授權策略,請求將被重新導向到這個相對路徑。

  4. 自動認證:這個標誌表明中介軟體應該會在每個請求上進行驗證和重建他建立的序列化主體。

  5. 自動挑戰:這個標誌標明當中介軟體認證失敗時應該重新導向瀏覽器到登入路徑或者禁止訪問路徑。

其他選項包括設定中介軟體所建立的聲明的發行者,中介軟體儲存的cookie名稱,Cookie的域和cookie上的各種安全屬性。預設情況下Cookie中介軟體將使用適當的安全選項,設定HTTPONLY避免cookie在用戶端被JavaScript操作。當請求方式為HTTPS時限制Cookie的HTTPS操作。

建立Cookie

建立Cookie儲存自己的資訊,必須要初始化一個ClaimsPrincipal(類型)來序列化和儲存你想儲存的使用者資訊到Cookie中。每一次的方法調用都會在你的Controller(控制器)中有一個合適的ClaimsPrincipal對象。

複製代碼 代碼如下:

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

上面的代碼將會建立一個加密的Cookie並且增加到當前的請求響應中。AuthenticationScheme明確規定在配置期間

退出

退出目前使用者的登入,刪除登入的cookie資訊,可以在控制器中調用下面的方法。

複製代碼 代碼如下:

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

響應後端的變化

警告

一旦cookie建立就會成為身份單一認證的來源,即使在後台系統已經不可用,中介軟體也是不知道的,並且始終保持登入直到cookie失效。

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

考慮到後台使用者的資料庫中可能會有‘最後的修改時間'這一列,為了在資料庫修改之後你可以廢止當前的Cookie,第一當建立這個Cookie時添加一個最後修改的聲明並包含當前的值,當資料庫中的資料改變時,這個值也同時更新。

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

Task ValidateAsync(CookieValidatePrincipalContext context);

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

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更新了,要想以不影響安全的方式你可以調用 context.ReplacePrincipal() 並且設定 context.ShouldRenew 為 true 。

控制Cookie選項

CookieAuthenticationOptions配備了各種各樣的配置選項是你能夠很好的調節建立的Cookie。

  1. ClaimsIssuer - 被用來在任何中介軟體建立的屬性之上。(看不懂)

  2. CookieDomain - 如果cookie domain被設定為 ** . http:// contoso.com ** 那麼 contoso.com, http://www. contoso.com,staging.contoso.com 等等類似這樣的網域名稱也會被允許。

  3. CookieHttpOnly - 這個標誌指示這個 cookie 只會被服務端訪問。預設值是true,修改這個屬性將會開放你的應用造成 Cookie 盜竊,造成跨站指令碼的bug。

  4. CookiePath - 這個可以用來隔離運行在同一個 host 下的應用。如果你有一個應用運行在 /app1 上,並且想限制 cookie 限制僅僅被發送給自己,那麼你應該設定 CookiePath 屬性為 /app1 ;Cookie將會明白只適用於道 /app1 或者他下面的請求。

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

  6. SlidingExpiration - 這個標誌標記了如果超過了到期時間的一半後被訪問那麼Cookie將會被重設。新的到期時間將會後移到目前時間加上ExpireTimespan之後。當調用 SignInAsync 時可以通過 ** AuthenticationProperties ** 設定絕對的到期時間。通過限制驗證cookie有效時間,絕對期滿可以提高應用程式的安全性。

持久性Cookie和絕對到期時間

您可能希望通過瀏覽器會話使cookie到期。也許你也想通過絕對到期時間和認證來結束cookie,那麼你可以在登入認證和建立Cookie時使用HttpContext.Authentication.SignInAsync方法中的AuthenticationProperties參數類實現。AuthenticationProperties類在Microsoft.AspNetCore.Http.Authentication命名空間中。

例如

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

這個程式碼片段將會實現建立一個認證和相應的Cookie來實現即時瀏覽器關閉Cookie也能繼續保留。任何在cookie屬性中的到期時間的設定都將會儲存下來。如果瀏覽器關閉時Cookie也到期了那麼在重新啟動瀏覽器是Cookie將會別清理。

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

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

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

// 1. 在Startup.cs的Configure方法中加上app.UseCookieAuthentication(new CookieAuthenticationOptions{ AuthenticationScheme = "UserAuth",  // Cookie 驗證方案名稱,在寫cookie時會用到。 AutomaticAuthenticate = true,     // 是否自動啟用驗證,如果不啟用,則即便客服端傳輸了Cookie資訊,服務端也不會主動解析。除了明確配置了 [Authorize(ActiveAuthenticationSchemes = "上面的方案名")] 屬性的地方,才會解析,此功能一般用在需要在同一應用中啟用多種驗證方案的時候。比如分Area. LoginPath = "/User/Index"     // 登入頁});// 2. 建立UserController// 3. 建立一個測試登入的方法(這裡為了方便測是我用的是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. 建立一個退出登入的方法public async Task<ActionResult> Logout(){ await HttpContext.Authentication.SignOutAsync("UserAuth"); // Startup.cs中配置的驗證方案名 return RedirectToAction("User", "Index");}// 5. 建立一個擷取cookie使用者資訊的方法方便調用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); }}// 或者寫一個測試Actionpublic 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");
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.