引言

在.NET里提供了FormsAuthentication类用来对用户身份进行验证和授权。不过,对于cookie的超时处理,一直是一个头疼的问题。这里介绍一下微软对.NET 身份验证超时的处理机制,不过我相信,这个机制并不是.NET所独有的,在你用任何语言(例如Java,Php,JS)等都会遇到这个问题,只是很多时候,我们不太在意这个问题。

问题的提出

我们通常使用cookie存放一下用户身份的信息,当然这些信息是加密的,然后输出到客户端,当用户提交时,在从cookie里获取这些信息,然后解密。其中很重要的一步是判断cookie有没有超时。考虑下面一种情况:一个用户与: 2020.3.9 10:00:00 登录一个系统,假设cookie的有效期为1个小时,也就是说 cookie将于 2020.3.9 11:00:00 失效。所以,服务器只要根据这个时间判断cookie是否失效即可,但是这个方式没有考虑时区。

例如:你的服务器是在“日本”,一个中国用户和一个美国用户访问该网站,登录后,服务器往这2个用户电脑上输出cookie,但是中美时区的不同,导致同一时刻,这2个用户看到的cookie日期出现了不同。因此,为了简化计划,在微软的.NET里,统一使用UTC时间,也就是世界标准时间。

在微软.NET的源代码里,给出了很大的注释来介绍这个问题。

https://referencesource.microsoft.com/#System.Web/Security/FormsAuthenticationTicket.cs,e565ecb38a6fa383

参考上面注释,就算使用UTC时间,仍然还有一些问题。

简单解释一下上图代码里的注释:为了方便.NET对时间处理,.NET时间统一采用UTC世界标准时,这样,一个北京用户 2020.3.9 10:00:00 登录系统,因为在+8区,所以,会在标准时的基础上加上+8,另外一个用户会在标准时的基础上-8,大致是这样的意思。

但是,不是每个开发者,每种开发语言都会采用类似这样的策略,.NET还需要考虑扩展性,因此,时间大致分文三种:
1.DateTime是UTC时间,这种最简单,直接处理。
2.DateTime是本地时间,.NET Framework会把他转换为UTC时间,同时,DateTime类在设计时预留了一个隐藏字段,他可以处理自定义时间(下述)。
3.DateTime的类型未知,考虑和早期.NET1.1兼容性,就把他归类为本地时间。

自定义夏令时

自定义时区曾经在中国使用过。正式的名称叫做“北京夏令时”,中国在1986年-1991年间实施的一种夏季时间制度,北京夏令时比标准的北京时间早一个小时。

夏令时,主要解决“感官”问题,例如:冬天的北京,晚上19:00 新闻联播时,天已经黑了,而夏天的北京,19:00天还亮,为了让夏天的北京19:00天也变黑,那时间往后退一个小时。

同样的还有美国时间,PDT是指太平洋夏季时间,PST是指太平洋标准时间。

从地缘政治上说,中国采用的是统一+8区,看地图都知道,中国地域广,全国使用同一时间可能并不是合理,

因为如果规定全国都是早上8点上班,可能东部的山东青岛已经天大亮,而西藏的日喀则可能还是深夜。同样,晚上8点东部天黑了,而西部天还是下午。

但是,北京夏令时的人为拨动时间,确实会打乱生成,因此在1991年停止使用。

但是在有些国家还是使用的,为此,DateTime类在设计时,包含了一个隐藏字段,来自定义夏令时。通过DateTimeOffset 属性校对时间。

绝对到期与顺滑到期

cookie过期的第二个问题是绝对过期与顺滑过期。如上 用户与 2020.3.9 10:00:00 登录系统,2020.3.9 11:00:00 cookie到期,这种记录方法被成为“绝对时间”,简单但是粗暴。试想一个用户在写一篇问题,他在

2020.3.9 11:00:01提交时,系统突然提示,身份过期,然后跳转到登录页面,所写的内容全部丢失,估计用户会欲哭无泪。(当然现在都有ajax在暗地里验证,不会出现这种问题了)。

在.NET里给出了一个 SlidingExpiration 属性,他会让cookie过期进行动态延长。默认值为true,

什么意思呢?下面是MSDN的解释: 如果发出了请求并且超过了一半的超时时间间隔,则滑动过期会重置有效身份验证 cookie 的过期时间。 如果 cookie 过期,用户必须重新进行身份验证。

也就是,虽然你的cookie会于2020.3.9 11:00:00 过期,但是.NET系统会自动给你延长。

在代码实现方面,如果查看.NET源代码,可以看到系统提供了 RenewTicketIfOld 方法,然后把这个方法注入到 OnAuthenticate事件,来事件动态延长。

https://referencesource.microsoft.com/#System.Web/Security/FormsAuthentication.cs,629

整个实现算法还是比较复杂的。需要考虑的细节太多。例如有些浏览器禁止使用cookie等情况。当然,这些复杂情况微软都被我们做了,我们直接用即可。

讨论一下.NET里,对cookie身份验证的超时的处理的更多相关文章

  1. asp.net core中使用cookie身份验证

    配置 在 Startup.ConfigureServices 方法中,创建具有 AddAuthentication 和 AddCookie 方法的身份验证中间件服务: services.AddAuth ...

  2. 简单服务器端Blazor Cookie身份验证的演示

    为了演示身份验证如何在服务器端 Blazor 应用程序中工作,我们将把身份验证简化为最基本的元素. 我们将简单地设置一个 cookie,然后读取应用程序中的 cookie. 应用程序身份验证 大多数商 ...

  3. ASP.NET MVC Cookie 身份验证

    1 创建一个ASP.NET MVC 项目 添加一个 AccountController 类. public class AccountController : Controller { [HttpGe ...

  4. 使用 cookie 的身份验证和授权

    前言 在上一章 学学 dotnet core 中的身份验证和授权-1-概念 中,我们大致明白了身份验证和授权两者的关系.那么在本文中,我们将使用 cookie 来做一个简单的身份验证和授权. 本文中我 ...

  5. asp.net core 3.x 身份验证-1涉及到的概念

    前言 从本篇开始将围绕asp.net core身份验证写个小系列,希望你看完本系列后,脑子里对asp.net core的身份验证原理有个大致印象.至于身份验证是啥?与授权有啥联系?就不介绍了,太啰嗦. ...

  6. asp.net core 3.x 身份验证-3cookie身份验证原理

    概述 上两篇(asp.net core 3.x 身份验证-1涉及到的概念.asp.net core 3.x 身份验证-2启动阶段的配置)介绍了身份验证相关概念以及启动阶段的配置,本篇以cookie身份 ...

  7. 从零搭建一个IdentityServer——聊聊Asp.net core中的身份验证与授权

    OpenIDConnect是一个身份验证服务,而Oauth2.0是一个授权框架,在前面几篇文章里通过IdentityServer4实现了基于Oauth2.0的客户端证书(Client_Credenti ...

  8. SQL Server安全(2/11):身份验证(Authentication)

    在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切.但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念.这篇文章提供了基础,因此你可以对SQL Se ...

  9. asp.net 解决IE11下 From身份验证失效问题

    指定如何将 Cookie 用于 Web 应用程序. <forms cookieless="UseCookies" name="test" loginUrl ...

随机推荐

  1. spring cloud关于feign client的调用对象列表参数、设置header参数、多环境动态参数试配

    spring cloud关于feign client的调用 1.有些场景接口参数需要传对象列表参数 2.有些场景接口设置设置权限等约定header参数 3.有些场景虽然用的是feign调用,但并不会走 ...

  2. 查看linux系统安装的服务

    如何查看linux系统安装了哪些服务呢,因不同版本的操作系统可能使用的命令不一样或者有些命令在某些操作系统不可用,现列举一些常用查看命令(基于我的linux版本). 我的操作系统版本如下: 1.ser ...

  3. VBA引用管理加载宏

    下载文件: VBA引用管理加载宏.rar 下载后,解压缩. Excel的 开发工具/加载项 在对话框中浏览 VBA引用管理.xlam VBA界面中,在工程右键菜单中出现:

  4. Git教程 - 远程仓库

    到目前为止,我们已经掌握了如何在Git仓库里对一个文件进行时光穿梭,你再也不用担心文件备份或者丢失的问题了. 可是有用过集中式版本控制系统SVN的童鞋会站出来说,这些功能在SVN里早就有了,没看出Gi ...

  5. Leetcode_开篇碎碎念

    已经计划写leetcode3天了,但是到目前为止一道题还没有写,执行力我太差了. 写leetcode的原因有两个,一是锻炼自己代码水平,提高实力:二是考研据了解到的都会有上机考试,基本是c++,jav ...

  6. C++中stoi函数

    作用: 将 n 进制的字符串转化为十进制 头文件: #include <string> 用法: stoi(字符串,起始位置,n进制),将 n 进制的字符串转化为十进制 示例: stoi(s ...

  7. CRISPR/Cas9|InParanoid|orthoMCL|PanOCT|pan genome|meta genome|Core gene|CVTree3|

    生命组学: 泛基因组学:用于描述一个物种基因组,据细菌基因组动力学,因为细菌的基因漂移使得各个细菌之间的基因组差异很大,(单个细菌之间的基因组差异是以基因为单位的gain&loss,而人类基因 ...

  8. svn merge Property conflicts

    svn merge代码的时候,出现Property conflicts的解决方案.可以参考:http://stackoverflow.com/questions/23677286/conflict-w ...

  9. 将本地的一个项目托管到自己的GitHub仓库

    GitHub作为全球最大的代码托管平台,功能十分强大.我们可以在上面建立一个仓库来托管我们的代码图片等资源.因为使用markdown语法来写博客所以在插入图片时需要一个图片外链地址,起初去网上找了一个 ...

  10. 360若真入股HTC 到底是谁来拯救谁

    到底是谁来拯救谁" title="360若真入股HTC 到底是谁来拯救谁"> 我总是持有一种观点,那就是拯救是相互的.就像老师拯救"堕落"学生, ...