ASP.NET Core Защита данных в веб-ферме - PullRequest
2 голосов
/ 24 мая 2019

У меня есть приложение ASP.NET Core, которое использует проверку подлинности cookie и работает в веб-ферме.Ключи защиты данных хранятся в БД.Мое приложение реализует IXmlRepository, и ASP.NET Core будет вызывать IXmlRepository.GetAllElements для получения кольца ключей.Таким образом, приложения во всех узлах используют одно и то же кольцо ключей, а cookie, зашифрованные в Node1, могут быть расшифрованы в Node2.Он работает нормально.

Однако срок действия ключа защиты данных истекает, и ASP.NET Core создает новый ключ.ASP.NET Core также кеширует ключи и будет обновляться каждые 18-24 часа.Таким образом, когда срок действия ключа истекает, Node1 может генерировать новый ключ, но все другие узлы могут не обновиться сразу и получить новый ключ.Cookie, зашифрованный Node1, не может быть дешифрован во всех других узлах.

Как эта ситуация может быть обработана ASP.NET Core?

Я прочитал это https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/web-farm?view=aspnetcore-2.2, В нем говорится

Конфигурация по умолчанию обычно не подходит для размещения приложений в веб-ферме.Альтернативой реализации общего набора ключей является всегда направлять пользовательские запросы на один и тот же узел.

Является ли это единственной возможностью направлять все запросы на один и тот же узел после входа пользователя в систему с использованием этого узла?

1 Ответ

0 голосов
/ 24 мая 2019

В принципе, это ничем не отличается от любого другого сценария общей конфигурации. Вам нужно сделать две вещи:

  1. Сохранить список ключей для общей файловой системы или сетевого пути, к которому могут обращаться все процессы / приложения:

    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));
    
  2. Убедитесь, что все процессы / приложения используют одно и то же имя приложения:

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

Второй элемент менее важен для сценария веб-фермы, поскольку это одно и то же приложение и по умолчанию будет иметь одно и то же имя. Однако всегда лучше быть явным, и тогда, если вам нужно поделиться с совершенно другим приложением, вы уже настроены и готовы к работе.

Короче говоря, вам нужно добавить следующий код:

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

К замечанию @ LGSon в комментариях под вашим вопросом, вы также в конечном итоге столкнетесь с проблемой кэширования / сессий. Независимо от того, чтобы быть одним и тем же «приложением», вы должны рассматривать каждый экземпляр веб-фермы как отдельное приложение. Каждый из них является отдельным процессом, что означает, что у них есть свое собственное выделение памяти. Если вы используете кеширование памяти (которое также является хранилищем по умолчанию для сеансов), то оно будет доступно только для отдельного процесса, который его создал. Поэтому каждый процесс будет иметь отдельный кеш и отдельные сеансы. Чтобы поделиться этой информацией, вам нужно использовать распределенный кеш, такой как Redis или SQL Server. Смотри: https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed?view=aspnetcore-2.2#establish-distributed-caching-services.

Примечание. Несмотря на то, что кэш-память «распределена», она фактически не распределена. Это просто реализация IDistributedCache, которая хранится в памяти. Поскольку он хранится в памяти, он все еще связан с процессом.

...