我们有一个 ASP.NET 核心 2.2 Web 应用程序,公开了一些 Web API 控制器。 我们的应用程序没有任何类型的身份验证机制,所有公开的端点都可以由匿名用户调用。
当我们在IIS下托管应用程序时,我们在应用程序启动时收到三条奇怪的警告消息。这些是我们得到的日志:
- 使用内存中存储库。密钥不会保留到存储中。
- 用户个人资料和 HKLM 注册表均不可用。使用临时密钥存储库。应用程序退出时,受保护的数据将不可用。
- 未配置 XML 加密器。密钥 {GUID} 可以以未加密的形式保存到存储中。
所有这些日志都将Microsoft.AspNetCore.DataProtection作为日志上下文,并由 ASP.NET 核心框架内部编写。
这些日志的含义对我来说似乎很清楚:有一个"密钥"(无论它意味着什么)将保留在内存中,因为没有提供注册表存储(当然,当应用程序退出时它会丢失)。还有一个警告,指示此密钥如果持久化,将不会以任何方式加密。
在这一点上,我会问以下问题:
- 日志中报告的名为"密钥"的 GUID 是什么?什么用途?
- 此警告是否存在任何安全风险?
- 我应该采取任何行动吗?
一些附加信息:
一些在线博客建议此类数据保护警告与 ASP.NET 身份的使用有关,但我们没有在我们的应用程序中使用身份(我们没有启用身份验证)。其他博客建议设置托管应用程序池以加载用户配置文件: 我已经尝试过了,但警告仍然存在。
重要更新 2nd 四月 2019
由于 asp.net 核心开发团队的帮助,我解决了这个问题。 有关完整的参考,请参阅我昨天打开的github问题
简而言之,问题与我的开发计算机上的 IIS 配置有关。为了使 ASP.NET 核心数据保护按预期工作,IIS 和宿主应用程序池有一些特定的配置(有关完整参考,请参阅此处)
更新 13th 九月 2019
对于那些在 ASP.NET 核心 2.2 Web 应用程序中具有相同警告的人,我建议看看这个 github 问题。
我们现在为我们的产品添加了 cookie 身份验证,我们需要支持 kubernetes 托管。在具有 cookie 身份验证的 kubernetes 中,此 stackoverflow 问题中讨论的警告是相关的,因为您必须为 ASP.NET 核心提供一个存储 ASP.NET 核心数据保护系统所需密钥的位置。
我们选择在MongoDB中实现一个持久密钥环。一些细节可以在这里找到。我不能在这里显示代码(该项目不是开源的),但我们基本上是从官方实体框架核心密钥环存储开始的,并将实体框架数据库上下文的所有用法替换为注入的IMongoCollection<DataProtectionKey>
。我们还通过删除 Id 属性修改了 DataProtectionKey 类(我们更喜欢让 MongoDB 生成自己的对象 ID)。
各种组件使用数据保护在运行时加密数据,例如:
- 身份验证饼干
- 标识密码重置令牌
您可以在文档中阅读有关它的更多信息:https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/introduction
您正确理解了警告,它已创建密钥,但无法决定将密钥存储在何处。 因此,如果应用程序重新启动,它将丢失。 如果您不使用身份验证 Cookie,则可以忽略这些警告。 您还可以在应用文件夹之外配置存储位置。
如果您没有使用任何身份验证机制(例如:ASP.NET 使用此类密钥的核心身份),并且如果您没有在其他地方使用数据保护API,那么(现在)就可以了。
那里发生了什么?
您输入了用于存储密钥(在内存存储中)的回退机制。重新启动应用时,你将丢失密钥。
你会面临什么问题?
示例:如果您使用的是身份验证机制,则最终会得到拧紧的身份验证cookie,电子邮件验证令牌,重置密码令牌等
你现在能做什么?
如果需要(面向未来的解决方案),您可以将密钥存储在某个地方(例如:Redis)。
延伸阅读: https://cypressnorth.com/programming/solved-using-memory-repository-keys-will-not-persisted-storage-asp-net-core-iis/
ASP.Net 核心数据保护将密钥存储在主目录(/root/.aspnet/DataProtection-Keys)中,因此当容器重新启动密钥丢失时,这可能会使服务崩溃。
这可以通过将密钥保留在
- 将密钥保留在持久位置(卷)并装载该卷 到 docker 容器 将密钥
- 保留在外部密钥存储(如 Azure 或 Redis )中
有关 ASP.NET 数据保护的更多详细信息:
https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-3.1
https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/introduction?view=aspnetcore-3.1
使用以下命令将外部卷 (C:/temp-kyes) 挂载到 docker 容器卷 (/root/.aspnet/DataProtection-Keys)
docker run -d -v /c/temp-keys:/root/.aspnet/DataProtection-Keys container-name
此外,还需要更新 Starup.cs - 配置服务以配置数据保护策略
services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(@"C:temp-keys"))
.UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration()
{
EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
});