Web场上的ASP.NET Core数据保护 [英] ASP.NET Core Data Protection on Web Farm

查看:147
本文介绍了Web场上的ASP.NET Core数据保护的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用Cookie身份验证并在Web场上运行的ASP.NET Core应用程序.数据保护密钥存储在DB中.我的应用程序实现了IXmlRepository,而ASP.NET Core将调用IXmlRepository.GetAllElements来获取密钥环.因此,所有节点中的应用程序都使用相同的密钥环,并且可以在Node2中解密在Node1中加密的cookie.效果很好.

I have a ASP.NET Core application that uses cookie authentication and runs on web farm. The data protection keys are stored in DB. My application implements the IXmlRepository and the ASP.NET Core will call the IXmlRepository.GetAllElements to get the key ring. So, application in all nodes are using the same key ring and cookie encrypted in Node1 can be decrypted in Node2. It works fine.

但是,数据保护密钥将过期,并且ASP.NET Core将生成一个新密钥.ASP.NET Core还会缓存密钥,并将每18-24小时刷新一次.因此,当密钥过期时,Node1可能会生成一个新密钥,但是所有其他节点可能不会立即刷新并获取新密钥.由Node1加密的Cookie不能在所有其他节点上解密.

However, data protection key will expire and ASP.NET Core will generate a new key. ASP.NET Core also cache the keys and will refresh each 18-24 hours. So, when the key expires, Node1 may generate a new key, but all other nodes may not refresh right away and get the new key. Cookie encrypted by Node1 cannot be decrypted in all other nodes.

ASP.NET Core如何处理这种情况?

How can this situation by handled by ASP.NET Core?

我阅读了此 https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/web-farm?view=aspnetcore-2.2 ,它指出

默认配置通常不适用于在Web场中托管应用程序.实现共享密钥环的另一种方法是始终将用户请求路由到同一节点.

The default configuration isn't generally appropriate for hosting apps in a web farm. An alternative to implementing a shared key ring is to always route user requests to the same node.

使用用户节点登录后,将所有请求路由到同一节点是唯一的选择吗?

Is it the only option to route all requests to the same node after user login using that node?

推荐答案

原则上,这与任何其他共享配置方案没有什么不同.您需要做两件事:

In principle, this is no different than any other shared configuration scenario. You need to do two things:

  1. 将密钥环保留到所有进程/应用程序可以访问的公用文件系统或网络位置路径:

  1. Persist the key ring to a common filesystem or network location path all the processes/apps can access:

services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));

  • 确保所有进程/应用程序都使用相同的应用程序名称:

  • Ensure that all the process/apps are using the same application name:

    services.AddDataProtection()
        .SetApplicationName("shared app name");
    

  • 第二项对于Web场方案而言不太重要,因为它都是相同的应用程序,并且默认情况下具有相同的应用程序名称.但是,最好明确一些,然后,如果您确实需要与一个完全不同的应用程序共享,那么您已经设置好并可以使用了.

    The second item is less important for a web farm scenario, since it's all the same app and will have the same app name by default. However, it's always better to be explicit, and then if you do need to share with an entirely different app, you're already set up and ready to go.

    简而言之,您需要添加以下代码:

    In short, you need to add the following code:

    services.AddDataProtection()
        .SetApplicationName("shared app name")
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));
    

    @LGSon在您的问题下方的评论中指出,最终您还将最终遇到缓存/会话问题.不管是相同的应用程序",您都应将Web场中的每个实例视为一个单独的应用程序.每个过程都是一个单独的过程,这意味着它们具有自己的单独的内存分配.如果您使用内存缓存(这也是会话的默认存储),那么该缓存将仅对创建它的单个进程可用.因此,每个进程将以单独的缓存和单独的会话结束.要共享此信息,您需要使用分布式缓存(例如Redis或SQL Server).请参阅: https://docs.microsoft.com/zh-cn/aspnet/core/performance/caching/distributed?view=aspnetcore-2.2# Establishment-distributed-caching-services .

    To @LGSon's point in the comments below your question, you'll also run into an issue with caching/sessions eventually, as well. Regardless of being the same "app", you should think of the each instance in the web farm as a separate app. Each is a separate process, which means they have their own separate memory allocation. If you use memory caching (which is also the default storage for sessions), then that will be available only to the individual process that created it. Each process will therefore end up with separate cache and separate sessions. To share this information, you need to employ a distributed cache like Redis or SQL Server. See: https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed?view=aspnetcore-2.2#establish-distributed-caching-services.

    注意:即使有分布式"内存缓存,它实际上并不是分布式的.这只是存储在内存中的 IDistributedCache 的实现.由于它存储在内存中,因此它仍然是进程绑定的.

    Note: Even though there's a "distributed" memory cache, it's not actually distributed. This is just an implementation of the IDistributedCache that stores in memory. Since it stores in-memory, it's still process bound.

    这篇关于Web场上的ASP.NET Core数据保护的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆