我在一些负载均衡的Linux服务器上部署了一个asp.net核心应用程序。由于ValidateAntiForgeryToken
属性失败(如果POST没有返回到生成我的表单的机器的同一台机器),在将表单发布到路由时出现错误。
使用Windows和.Net classic,我知道我的MachineKey
或web.config
文件中的machine.config
属性匹配。
那么,我如何在linux主机上实现相同的功能,并允许来自一台服务器的令牌在另一台服务器上验证呢?
答案 0 :(得分:8)
当您致电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存储的选项。
进行测试
默认情况下,令牌的有效期为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%确定如果您尝试使用注册表选项会发生什么......