LUKIYA'S NEVERLAND

春去秋来,花谢花开。


        用户登录后产生的Cookie,使用IDataProtector.Protect(...)和IDataProtector.Unprotect(...)进行加密和解密。在这个过程中,IDataProtector需要使用Data Protection Key。

    Asp.NET Core 默认内置了三种Data Protection Key的存储方式,分别为文件系统、注册表、以及内存。程序启动时,会首先选择文件系统存储和读取,如果没有读写文件系统的权限,则转用注册表。如果独写注册表再失败,就会使用内存来存储Data Protection Key。

    从最初测试写邮件跟我反映这个问题一直到昨天,我都无法重现这个问题。这是因为开发都是用控制台启动,而且都是管理员权限,因此具备读写文件系统和注册表的权限。

    但是,发布到IIS后,IIS的进程是不具备这样的权限的,因此它会使用内存来存储Data Protection Key。当IIS的进程池自动回收后,所有已经登录人员的Cookie无法被解密,造成身份票据被Asp.NET Core判断为无效,表现出来的结果就是用户失去登录状态。

    失去登录状态则无法读取访问令牌,因此报Unauthorized错误。

解决方案:

    方案1: 提高IIS进程的权限级别(安全问题,不推荐)

    方案2: 将IIS进程池设置为不自动回收(重启服务器依然有问题,不推荐)

    方案3: 使用其他的Key仓储器

由上可见,只有第三种方案是最稳定和安全的。官方提供了两种额外的仓储器,分别是Azure的和Redis的。

也可以自己实现IXmlRepository接口,往更多可选存储写入和读取。