我如何跨 linux 个服务器处理 ValidateAntiForgeryToken
How do I handle ValidateAntiForgeryToken across linux servers
我已经在一些负载平衡的 linux 服务器上部署了一个 asp.net 核心应用程序。由于失败的 ValidateAntiForgeryToken
属性(如果 POST 没有返回到与生成我的表单的机器相同的机器,我在将表单 POST 发送到路由时收到错误消息.
使用 Windows 和 .Net classic 我知道可以匹配 web.config
或 machine.config
文件中的 MachineKey
属性。
那么,如何在 linux 主机上实现相同的目的并允许来自一台服务器的令牌在另一台服务器上进行验证?
因此当您调用 services.addMvc()
时会自动添加防伪支持。您可以通过调用 services.AddAntiforgery(opts => "your options")
来更改基本配置。
在幕后,令牌受 ASP.Net Core Data Protection library (github repo here) 保护。默认情况下,我认为这是在内存中,因此生成的密钥,然后用于令牌保护,不会在多个/云服务器场景中共享。
解决方案
因此,要共享防伪令牌,您可以设置具有共享位置的数据保护服务。数据保护库自带的默认是:
//File system
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\some\shared\directory\"));
//Registry
services.AddDataProtection()
.PersistKeysToRegistry(Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Sample\keys"));
然后有几个默认值包括更好的共享存储:
//redis
var redis = ConnectionMultiplexer.Connect("my-redis-url");
services.AddDataProtection()
.PersistKeysToRedis(redis, "DataProtection-Keys");
//Azure
services.AddDataProtection()
.PersistKeysToAzureBlobStorage(new Uri("blob-URI"));
我还发现(并使用了!)来自 github thanks to a github user named CL0SeY 的 AWS S3 存储选项。
更新:Amazon 也发布了他们自己的使用 AWS SSM 参数存储的实现。 Github repo here。
用于测试
默认情况下,令牌的有效期为 90 天。这可以在您添加服务时设置。因此,获得简单测试解决方案的一种方法是为文件系统生成具有较长生命周期的密钥,然后将该令牌部署到服务器上的已知位置。然后从该位置设置数据保护,但告诉它永远不要生成新密钥:
//generate a test key with this in a test app or whatever:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"c:\temp\"))
.SetDefaultKeyLifetime(TimeSpan.MaxValue);
// then use that key in your app:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\some\allowed\directory"))
.DisableAutomaticKeyGeneration();
上linux
当托管在 linux 上时,所有这些都应该有效,唯一的警告是您不应该引用 windows 驱动器或位置(duh)。我不是 100% 确定如果您尝试注册表选项会发生什么...
我已经在一些负载平衡的 linux 服务器上部署了一个 asp.net 核心应用程序。由于失败的 ValidateAntiForgeryToken
属性(如果 POST 没有返回到与生成我的表单的机器相同的机器,我在将表单 POST 发送到路由时收到错误消息.
使用 Windows 和 .Net classic 我知道可以匹配 web.config
或 machine.config
文件中的 MachineKey
属性。
那么,如何在 linux 主机上实现相同的目的并允许来自一台服务器的令牌在另一台服务器上进行验证?
因此当您调用 services.addMvc()
时会自动添加防伪支持。您可以通过调用 services.AddAntiforgery(opts => "your options")
来更改基本配置。
在幕后,令牌受 ASP.Net Core Data Protection library (github repo here) 保护。默认情况下,我认为这是在内存中,因此生成的密钥,然后用于令牌保护,不会在多个/云服务器场景中共享。
解决方案
因此,要共享防伪令牌,您可以设置具有共享位置的数据保护服务。数据保护库自带的默认是:
//File system
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\some\shared\directory\"));
//Registry
services.AddDataProtection()
.PersistKeysToRegistry(Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Sample\keys"));
然后有几个默认值包括更好的共享存储:
//redis
var redis = ConnectionMultiplexer.Connect("my-redis-url");
services.AddDataProtection()
.PersistKeysToRedis(redis, "DataProtection-Keys");
//Azure
services.AddDataProtection()
.PersistKeysToAzureBlobStorage(new Uri("blob-URI"));
我还发现(并使用了!)来自 github thanks to a github user named CL0SeY 的 AWS S3 存储选项。
更新:Amazon 也发布了他们自己的使用 AWS SSM 参数存储的实现。 Github repo here。 用于测试
默认情况下,令牌的有效期为 90 天。这可以在您添加服务时设置。因此,获得简单测试解决方案的一种方法是为文件系统生成具有较长生命周期的密钥,然后将该令牌部署到服务器上的已知位置。然后从该位置设置数据保护,但告诉它永远不要生成新密钥:
//generate a test key with this in a test app or whatever:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"c:\temp\"))
.SetDefaultKeyLifetime(TimeSpan.MaxValue);
// then use that key in your app:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\some\allowed\directory"))
.DisableAutomaticKeyGeneration();
上linux
当托管在 linux 上时,所有这些都应该有效,唯一的警告是您不应该引用 windows 驱动器或位置(duh)。我不是 100% 确定如果您尝试注册表选项会发生什么...