app.UseCookieAuthentication(options => { options.Events = new CookieAuthenticationEvents { // Set other options OnValidatePrincipal = LastChangedValidator.ValidateAsync }; });
如果你想非破坏性的更新用户主体,例如,name更新了,要想以不影响安全的方式你可以调用context.ReplacePrincipal() 并且设置 context.ShouldRenew 为 true。
控制Cookie选项CookieAuthenticationOptions 配备了各种各样的配置选项是你能够很好的调节创建的Cookie。
ClaimsIssuer - 被用来在任何中间件创建的属性之上。(看不懂)
CookieDomain - 如果cookie domain被设置为 ** .contoso.com** 那么contoso.com,contoso.com,staging.contoso.com 等等类似这样的域名也会被允许。
CookieHttpOnly - 这个标志指示这个 cookie 只会被服务端访问。默认值是true,修改这个属性将会开放你的应用造成 Cookie 盗窃,造成跨站脚本的bug。
CookiePath - 这个可以用来隔离运行在同一个 host 下的应用。如果你有一个应用运行在/app1 上,并且想限制 cookie 限制仅仅被发送给自己,那么你应该设置 CookiePath 属性为 /app1 ;Cookie将会明白只适用于道 /app1 或者他下面的请求。
ExpireTimeSpan - 这个 TimeSpan 时间段之后 Cookie 将会过期。
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); } } // 或者写一个测试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");