MVC 6 WebFarm:无法解密防伪令牌 [英] MVC 6 WebFarm: The antiforgery token could not be decrypted
问题描述
我在webfarm场景(具有多个AppServer的ARR前端)中运行MVC 6(vNext)。服务器关联关闭。
I'm running MVC 6 (vNext) in a webfarm scenario (ARR front-end with multiple AppServers). Server affinity is off.
当我在应用服务器之间从一个请求跳到另一个请求时,我收到错误
When I bounce between app servers from one request to another I get the error
CryptographicException:密钥环中找不到密钥{3275ccad-973d-43ca-930f-fbac4d276640}。
CryptographicException: The key {3275ccad-973d-43ca-930f-fbac4d276640} was not found in the key ring.
InvalidOperationException:防伪令牌无法解密。
InvalidOperationException: The antiforgery token could not be decrypted.
以前,我认为这是通过在web.config中设置静态MachineKey来处理的。
Previously, I believe this was handled by setting a static MachineKey in the web.config.
据我了解,我们现在已经转移到新的DataProtection API,我尝试了以下内容,认为应用程序名称被用作某种种子:
As I understand it, we've now moved to a new DataProtection API and I've tried the following, thinking the application name is used as some kind of seed:
services.AddDataProtection();
services.ConfigureDataProtection(configure =>
{
configure.SetApplicationName("WebAppName");
});
这不能解决问题。
知道如何在vNext中解决这个问题吗?
Any idea how to solve this issue in vNext?
推荐答案
解释
您需要重复使用相同的密钥。
Explanation
You'll need to reuse the same key.
如果您使用的是Azure,则密钥会在%HOME%\ ASP.NET \ DataProtection-Keys上由NAS类型存储同步
。
If you are on Azure, the keys are synced by NAS-type storage on %HOME%\ASP.NET\DataProtection-Keys
.
对于本地运行的应用程序,它们存储在%LOCALAPPDATA%\ ASP.NET \ DataProtection中-Keys
运行应用程序或存储在注册表中的用户,如果它在IIS中执行。
For locally run application, they are stored in the %LOCALAPPDATA%\ASP.NET\DataProtection-Keys
of the user running the application or stored in the registry if it's being executed in IIS.
如果以上都不匹配,则密钥是在流程的生命周期内生成的。
If none of the above match, the key is generated for the lifetime of the process.
因此第一个选项不可用(Azure只要)。但是,您可以在运行应用程序的每台计算机上同步运行应用程序的用户的%LOCALAPPDATA%\ ASP.NET \DataProtection-Keys
中的密钥。
So the first option is not available (Azure only). However, you could sync the keys from %LOCALAPPDATA%\ASP.NET\DataProtection-Keys
of the user running your application on each machine running your application.
但更好的是,您可以将它指向这样的网络共享:
But even better, you could just point it to a network share like this:
sc.ConfigureDataProtection(configure =>
{
// persist keys to a specific directory
configure.PersistKeysToFileSystem(new DirectoryInfo(@"Z:\temp-keys\"));
});
这将允许您在保持安全的同时进行扩展。
This will allow you to scale while keeping your security.
重要提示:您的密钥将每90天过期一次。经常重新生成它们很重要。
Important: Your keys will expire every 90 days. It will be important to regenerate them frequently.
您可以使用这段代码更改它,但更短,更安全。
You can change it using this bit of code but the shorter, the safer you are.
services.ConfigureDataProtection(configure =>
{
// use 14-day lifetime instead of 90-day lifetime
configure.SetDefaultKeyLifetime(TimeSpan.FromDays(14));
});