Сеанс пользователя.Net Core 2.x неожиданно завершает работу на Shared Hosting
Я играю с шаблоном aspnetboilerplate.com для ядра dotnet. Я пытаюсь развернуть шаблон на сервере общего хостинга (windows) под управлением Plesk (обратите внимание, я вообще не контролирую сервер).
Шаблон отлично работает локально, может входить в систему, добавлять пользователей, роли и т. Д. При его развертывании на сервере общего хостинга возникли некоторые проблемы, но это было решено относительно быстро (настройка для ядра dotnet и пришлось перейти на ядро dotnet 2.1, так как 2.2 не пока поддерживается на сервере).
Проблема сейчас в том, что после входа в систему, через минуту я перенаправил на страницу входа. У меня была похожая проблема с ASP.NET MVC5, но предоставление машинного ключа в web.config и использование базы данных для данных сеанса устранило эту проблему. Поэтому я полагаю, что это та же проблема с приложением dotnet.
Но поскольку ядро dotnet не использует машинные ключи и DataProtectionApis, необходим другой подход.
Итак, я попытался добавить services.AddDataProtection();
в StartUp.Configure()
Я прочитал Распределенное кеширование в ASP.NET Core и почти все ссылки там, а также попробовал несколько примеров кода, но либо я не знаю, что я делаю (высокая вероятность), либо я делаю что-то не так.
Итак, как я могу предотвратить неожиданный выход пользователя из системы с помощью dotnet core 2.1 на сервере общего хостинга?
РЕДАКТИРОВАТЬ - 2019-01-25
Некоторая новая информация: Попытка установить тайм-ауты как предложено, но это либо ничего не делает, либо невозможно. Чтобы приложение dotnet работало на Plesk, мне пришлось отключить поддержку ASP.NET, чтобы ядро .NET получило пул приложений без управляемого кода. Попытка получить доступ к настройкам ASP.Net в Plesk (где у вас будет доступ к настройке пула приложений и т. Д.) Приводит к ошибке "Поддержка ASP.NET для этого веб-сайта".
Единственное, чего не происходит, это то, что папка App_Data/Logs никогда не создается при публикации. Мне пришлось вручную создавать и устанавливать разрешения, чтобы log4net мог создать файл журнала. Файл журнала предоставил мне дополнительную информацию:
ERROR 2019-01-25 09:33:03,005 [6 ] .Antiforgery.Internal.DefaultAntiforgery - An exception was thrown while deserializing the token.
Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The antiforgery token could not be decrypted. ---> System.Security.Cryptography.CryptographicException: The key {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} was not found in the key ring.
Поиск этой ошибки только еще раз привел меня к документации о добавлении services.AddDataProtection()
к методу ConfigureServices, но это напоминает о хранилищах ключей Azure (или других внешних провайдерах) или записи информации в общий UNC, чтобы другие серверы могли получить доступ к информации из кэшированного ключа (и это, вероятно, то, что мне нужно). Но, поскольку все эти опции мне недоступны, я нашел метод расширения, который позволяет хранить ключ на сервере MSSQL. Занят, настраивая это сейчас, чтобы проверить.
Если кто-то хочет высказать свое мнение, пожалуйста, будьте моим гостем.
ОБНОВЛЕНИЕ 2 - 2019-01-25 - УСПЕХ (пока)
Казалось бы, использование DataProtectionAPI - это путь. Логи не сообщают ни о каких AntiforgeryValidationException
, еще. Я собираюсь дать ему поработать некоторое время, и если все будет хорошо, я опубликую решение и как оно было реализовано.
2 ответа
Как PersistKeysToSqlServer
не поддерживается в dot net core 3.1, мы можем использовать .PersistKeysToDbContext<AppDBContext>()
или PersistKeysToFileSystem
как показано здесь.
Исходя из информации, которую вы предоставили выше, я считаю, что ваше заседание истекло.
Когда время сеанса истечет, пользователь будет перенаправлен на страницу входа для повторной аутентификации. Я не слишком знаком с plesk, но из-за очень быстрого поиска в Google кажется, что вы сможете увеличить время ожидания сессии.
Конечно, если вы устанавливаете время ожидания сеанса самостоятельно в configurservices, вы можете просто настроить его там, как я полагаю (опять же, незнакомый с настройкой plesk полностью).
Если вы это сделаете, проблема должна разрешиться сама собой. Возможно, время ожидания сеанса установлено на короткий период времени для тестирования?
состояние сеанса.net
services.AddSession(options =>
{
// Set a short timeout for easy testing.
options.IdleTimeout = TimeSpan.FromSeconds(10);
options.Cookie.HttpOnly = true;
});
Общий хостинг имеет некоторые ограничения для вашего пула приложений. Вы можете проверить значение "Idle Timeout" на панели инструментов Plesk. Поэтому в главной панели инструментов нажмите "Пул выделенных приложений для веб-сайта" и проверьте указанное значение. Я не уверен в том, что установка времени ожидания простоя через ваш код решает вашу проблему, но поддержка поставщика услуг может легко установить его для вас на пользовательское значение.
Оказывается, проблема была не в истечении сеанса, а в том, что когда другой сервер принимает на себя нагрузку на мой сайт, у него нет контекста сеанса. Службы защиты данных позволяют создавать базу данных, в которой хранится информация о сеансе, и она распределяется между серверами в ферме. Аналогично атрибуту состояния сеанса из web.config в проектах MVC:
<sessionState mode="SQLServer" sqlConnectionString="Data Source=000.000.000.000;Initial Catalog=session_db;User Id=user;Password=password;" allowCustomSqlDatabase="true" timeout="480" />
Вот как я решил проблему:
В ConfigureServices я добавил:
services.AddDataProtection()
.SetApplicationName("MyApplicationName")
.SetDefaultKeyLifetime(TimeSpan.FromDays(14))
.PersistKeysToSqlServer(_config["DataProtection:SqlServerConnectionString"]);
Мне также пришлось создать отдельную базу данных, которая отвечает за хранение информации о сеансе. DataProtextion:SqlServerConnectionString
это запись в appsettings.json
файл:
"DataProtection":
{
"SqlServerConnectionString": "Server=server; Database=database; User=user; Password=password;"
}
Возможно, есть способы решить эту проблему (например, с помощью Redis), но, поскольку у меня нет контроля над сервером, на котором размещен мой сайт, службы защиты данных работают просто отлично.