Docker部署ASP.NET Core是否需配置持久化DataProtection密钥?
你在Docker日志里看到的是ASP.NET Core内置数据保护(DataProtection,后面简称DP)组件的默认提示,原始日志如下:
[08:20:54 WRN] Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. <s:Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository> [08:20:54 WRN] No XML encryptor configured. Key {<some-id>} may be persisted to storage in unencrypted form. <s:Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager>
DP不是只服务于Identity框架、会话Cookie的组件,它是ASP.NET Core底层的通用加解密栈,很多内置功能默认就会依赖它,哪怕你从来没主动调用过DP的接口:
- 内置的CSRF防伪令牌生成、校验逻辑全程走DP加解密
- TempData、Cookie认证中间件的默认数据保护逻辑依赖DP
- 不少第三方组件、OAuth/OpenID Connect相关的临时状态加密,都会默认调用DP
你自己手动生成JWT签名密钥、自行处理业务文本加解密的逻辑,和DP生成的这套密钥完全无关,这部分自定义逻辑不会受DP密钥丢失的影响。
DP默认初始化的逻辑是ASP.NET Core Web应用启动时自动触发的,不需要你手动开启,所以只要你跑的是Web应用,容器里基本都会看到这个提示。
完全看你的部署场景,没有统一答案:
可以直接忽略的情况
同时满足以下所有条件的话,你完全不用管这两个警告,不会影响业务:
- 单实例部署,没有多副本负载均衡的需求
- 没有任何经DP加密的数据需要跨容器生命周期留存:比如你没有把DP加密后的内容存到数据库、长期缓存、客户端长期Cookie里
这种场景下容器销毁时密钥跟着丢了也没关系,最多是容器重启后之前下发的短期CSRF令牌、临时状态失效,用户刷新下页面就能恢复,不会出现数据解密失败的报错。
至于第二个“密钥未加密存储”的警告,在隔离的容器环境里基本没有风险,你没把密钥目录挂载暴露给不可信进程的话,完全不用额外配置加密。
必须做持久化配置的情况
只要符合下面任意一条,就必须把DP密钥存到容器外的持久化存储,不然一定会出故障:
- 多实例部署:多个容器副本必须共享同一套DP密钥,不然一个实例加密的内容其他实例解不开,会直接抛异常
- 存在经DP加密的长期有效数据:比如把DP加密后的内容持久化到数据库、客户端Cookie设置了很长的有效期,需要跨容器重启/重建后正常解密
- 需要做滚动发布、无中断更新:避免更新容器时用户状态失效
Docker环境下最省事的配置方式就是把/root/.aspnet/DataProtection-Keys目录挂载到宿主机持久化卷或者共享存储,多实例场景下所有副本挂载同一个共享目录即可;你也可以在应用启动代码里显式指定DP的密钥存储位置、配置密钥的加密方式,直接消掉这两个警告。

内容的提问来源于stack exchange,提问作者srzsanti

