在 IIS 中 运行 时,AspNet Core 在内存回购中使用数据保护

AspNet Core using in memory repo for data protection when running in IIS

我是 运行 生产服务器 (Windows Server 2012),有一个 AspNet Mvc Core RC1 网站。

我在日志中看到以下内容:

Neither user profile nor HKLM registry available. Using an ephemeral key repository. Protected data will be unavailable when application exits.

检查 DataProtection 的源代码后,我将问题跟踪到以下方法调用:

Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)

这可能由于某种原因在服务器上返回空值。我没有任何特殊的自定义配置,我已经阅读了 docs,所以我认为默认设置会起作用。

我认为问题出在 IIS 网站上,而不是 运行 在特定用户的上下文中,但我不知道如何确认或修复此问题。我的网站配置了自己的池。

顺便说一句: 运行 用于存储密钥的内存存储库导致它们在应用程序退出时回收,这非常烦人,甚至不是故意的用于生产环境。

应在 IIS 配置中加载用户配置文件。

打开 IIS,右键单击“应用程序池”,然后单击“高级设置”。并将 "Load user profile" 设置为 true。重新启动您的应用程序,它应该可以正常运行。

ASP.NET 应用程序使用的数据保护密钥存储在应用程序外部的注册表配置单元中。当 运行 您的应用程序作为 AppPool Identity 时,您必须为 每个与 ASP.NET Core 应用程序一起使用的 AppPool 创建一个注册表配置单元。

对于独立的 IIS 安装,您可以为与 ASP.NET 核心应用程序一起使用的每个应用程序池 使用 Data Protection PowerShell script 。密钥将保留在注册表中。

就像日志中明确指出的那样,因为数据保护查找的注册表配置单元不存在,所以密钥不会保存到磁盘。相反,它们将是短暂的并且仅存在于内存中。

在网络场场景中,应用程序可以配置为使用 UNC 路径来存储其数据保护密钥环。默认情况下,数据保护密钥未加密。你可以部署一个x509证书到每台机器来加密密钥环。

有关详细信息,请参阅 official ASP.NET Core doc about data-protection

看看this from the DataProtection Git repository

简而言之,IIS 中存在一个可能永远无法更正的错误,它会阻止正确设置 DataProtection 密钥的注册表。有一个 powershell script 可以正确手动设置注册表,以便它适用于 AspNet Core。在您 运行 用于 AspNet Core 应用程序的每个应用程序池的脚本之后,这些应用程序将按预期工作。

在访问权限非常有限的托管环境中的用户可以改用 PersistKeysToFileSystem。 将以下列表添加到 Startup.cs 将解决您的问题:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\server\share\directory\"));
}

您可以根据需要更改路径字符串。 如果您想通过调用任何 ProtectKeysWith* 配置 API 将系统配置为保护静态密钥,请同时检查 ProtectKeysWith