kkl*_*klo 7 data-protection web-farm asp.net-core
我有一个 ASP.NET Core 应用程序,它使用 cookie 身份验证并在 Web 场上运行。数据保护密钥存储在 DB 中。我的应用程序实现了 IXmlRepository,ASP.NET Core 将调用 IXmlRepository.GetAllElements 来获取密钥环。因此,所有节点中的应用程序都使用相同的密钥环,并且在节点 1 中加密的 cookie 可以在节点 2 中解密。它工作正常。
但是,数据保护密钥将过期,ASP.NET Core 将生成新密钥。ASP.NET Core 还会缓存密钥,并将每 18-24 小时刷新一次。所以,当key过期时,Node1可能会生成一个新的key,但是其他所有的节点可能不会马上刷新并得到新的key。节点 1 加密的 Cookie 无法在所有其他节点中解密。
ASP.NET Core 如何处理这种情况?
我读了这个https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/web-farm?view=aspnetcore-2.2,它指出
默认配置通常不适用于在 Web 场中托管应用程序。实现共享密钥环的另一种方法是始终将用户请求路由到同一节点。
用户使用该节点登录后,这是将所有请求路由到同一节点的唯一选择吗?
原则上,这与任何其他共享配置方案没有什么不同。你需要做两件事:
将密钥环保留到所有进程/应用程序可以访问的公共文件系统或网络位置路径:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));
Run Code Online (Sandbox Code Playgroud)确保所有进程/应用程序都使用相同的应用程序名称:
services.AddDataProtection()
.SetApplicationName("shared app name");
Run Code Online (Sandbox Code Playgroud)第二项对于 Web 场方案不太重要,因为它们都是相同的应用程序,并且默认情况下具有相同的应用程序名称。但是,明确总是更好,然后如果您确实需要与一个完全不同的应用程序共享,那么您已经准备就绪并准备好了。
简而言之,您需要添加以下代码:
services.AddDataProtection()
.SetApplicationName("shared app name")
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));
Run Code Online (Sandbox Code Playgroud)
对于@LGSon 在您的问题下方的评论中的观点,您最终也会遇到缓存/会话问题。不管是同一个“应用程序”,您都应该将 Web 场中的每个实例视为一个单独的应用程序。每个都是一个单独的进程,这意味着它们有自己单独的内存分配。如果您使用内存缓存(这也是会话的默认存储),那么它将仅对创建它的单个进程可用。因此,每个进程都会以单独的缓存和单独的会话结束。要共享此信息,您需要使用分布式缓存,如 Redis 或 SQL Server。请参阅:https : //docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed?view=aspnetcore-2.2#establish-distributed-caching-services。
注意:即使有一个“分布式”内存缓存,它实际上并不是分布式的。这只是IDistributedCache
存储在内存中的 的实现。因为它存储在内存中,所以它仍然是进程绑定的。
归档时间: |
|
查看次数: |
2284 次 |
最近记录: |