0

我正在玩aspnetboilerplate.com 的dotnet core 模板。我想要做的是将模板部署在运行 Plesk 的共享主机(Windows)服务器上(注意,我根本无法控制服务器)。

该模板在本地完美运行,可以登录、添加用户、角色等。将其部署到共享托管服务器出现了一些问题,但相对较快地解决了(为 dotnet core 配置并且必须降到 dotnet core 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 核心获得无托管代码应用程序池。尝试访问 Plesk 上的 ASP.Net 设置(您可以访问应用程序池设置等)会出现错误,提示“此网站的 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 Key Vaults(或其他外部提供程序)或将信息写入共享 UNC 以便其他服务器可以访问缓存的密钥信息(和这可能是我需要的)。但是由于我无法使用所有这些选项,因此我找到了一种扩展方法,该方法允许将密钥存储在 MSSQL 服务器上。现在正忙于设置它以进行测试。

如果有人想发表意见,请成为我的客人。

更新 2 - 2019-01-25 - 成功(暂时)

看来使用 DataProtectionAPI 是要走的路。日志还没有报告任何AntiforgeryValidationException。我将让它运行一段时间,如果一切顺利,我将发布解决方案以及它是如何实施的。

4

3 回答 3

1

由于PersistKeysToSqlServerdot net core 3.1 不支持,我们可以使用.PersistKeysToDbContext<AppDBContext>()PersistKeysToFileSystem,如图所示

于 2020-05-07T20:41:52.933 回答
1

根据您在上面提供的信息,我相信您的会话正在超时。

当会话超时时,用户将被重定向到登录页面以重新进行身份验证。我对 plesk 并不太熟悉,但是从非常快速的谷歌搜索来看,您似乎应该能够增加会话超时。

当然,如果您自己在 configurservices 中设置 sessiontimeout,您也可以在那里调整它,我会假设(再次完全不熟悉 plesk 设置)。

如果你这样做,问题应该会自行解决。也许会话超时设置为较短的测试时间?

.net 会话状态

services.AddSession(options =>
        {
            // Set a short timeout for easy testing.
            options.IdleTimeout = TimeSpan.FromSeconds(10);
            options.Cookie.HttpOnly = true;
        });
于 2019-01-24T19:16:55.537 回答
0

事实证明,问题不是会话到期,而是当另一台服务器接管我的站点的负载时,它没有会话上下文。数据保护服务允许创建一个数据库来存储会话信息,并在场中的服务器之间共享。类似于 MVC 项目中 web.config 中的会话状态属性:

<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:SqlServerConnectionStringappsettings.json文件中的一个条目:

"DataProtection":
    {
        "SqlServerConnectionString": "Server=server; Database=database; User=user; Password=password;"
    }

可能有一些方法可以解决这个问题(例如使用 Redis),但由于我无法控制我的站点所在的服务器,因此数据保护服务工作得很好。

于 2019-04-16T11:01:38.500 回答