.Net核心机器密钥替代Webfarm [英] .Net Core Machine Key alternative for webfarm
问题描述
我一直在使用dotnet核心来创建一个在Linux主机上的Kubernetes集群中运行的应用程序.当我进行测试时,它注意到验证CSRF令牌时会出现异常,这是有道理的,因为我尚未将机器密钥编辑为在每个实例上都相同.当我继续在web.config中设置机器密钥时,我注意到这在.Net Core中将不再起作用.
I have been using dotnet core to create an application that runs in a Kubernetes cluster on Linux hosts. As I was testing it noticed getting exceptions when validating the CSRF tokens, that makes sense since I did not edit the machine key to be the same on every instance yet. As i proceeded to set the machine key in web.config i noticed this would no longer work in .Net Core.
由于现在正在使用DataProtection API,因此机器密钥不再起作用.我尝试将api实现到我的应用程序中,但是当我阅读时,我将需要使用网络共享在所有实例之间交换密钥,这让我很震惊.当然,必须有一种更轻松(更好)的方法来完成此任务,而不必依靠共享来实现在线权利吗?
As is is now using the DataProtection API, the machine key no longer worked. I tried implementing the api into my application, but when i read i would need to use a network share to exchange the keys between all instances i was stunned. Surely there must be an easier (and better) way to accomplish this without having to rely on a share to be online right?
我尝试在ConfigureServices方法的Startup类中设置以下内容:
i tried to set the following in the Startup class in the ConfigureServices method:
services.AddDataProtection().SetApplicationName("DockerTestApplication");
我不知何故希望使用应用程序名称生成密钥,但这不能解决问题.
I somehow expected the keys to be generated using the applicationname, but this did not resolve the issue.
我找到了一些有趣的文档,这些文档都使用了将不再编译的代码,我想Microsoft做了一些改动:
I found some interesting docs that all use code that will no longer compile, i guess Microsoft changed up some things:
有人知道这个问题的解决方案也将在Linux上运行,并且能够在实例之间通过网络共享令牌吗?
Does anyone know a solution to this problem that will also run on Linux and has the ability to share the tokens over the network between instances?
提前谢谢!
推荐答案
我已经进行了一些测试,以备份我对复制密钥的评论.首先,我使用以下代码创建了简单的控制台应用程序:
I've made some tests to back up my comment about copying keys. First I created simple console application with the following code:
var serviceCollection = new ServiceCollection();
serviceCollection.AddDataProtection()
.SetApplicationName("my-app")
.PersistKeysToFileSystem(new DirectoryInfo(@"G:\tmp\so\keys"));
var services = serviceCollection.BuildServiceProvider();
var provider = services.GetService<IDataProtectionProvider>();
var protector = provider.CreateProtector("some_purpose");
Console.WriteLine(Convert.ToBase64String(protector.Protect(Encoding.UTF8.GetBytes("hello world"))));
因此,只需创建DI容器,在其中使用密钥的特定文件夹注册数据保护,然后解决并保护某些东西即可.
So, just create DI container, register data protection there with specific folder for keys, resolve and protect something.
这将在目标文件夹中生成以下密钥文件:
This generated the following key file in target folder:
<?xml version="1.0" encoding="utf-8"?>
<key id="e6cbce11-9afd-43e6-94be-3f6057cb8a87" version="1">
<creationDate>2017-04-10T15:28:18.0565235Z</creationDate>
<activationDate>2017-04-10T15:28:18.0144946Z</activationDate>
<expirationDate>2017-07-09T15:28:18.0144946Z</expirationDate>
<descriptor deserializerType="Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
<descriptor>
<encryption algorithm="AES_256_CBC" />
<validation algorithm="HMACSHA256" />
<masterKey p4:requiresEncryption="true" xmlns:p4="http://schemas.asp.net/2015/03/dataProtection">
<!-- Warning: the key below is in an unencrypted form. -->
<value>rVDib1M1BjbCqGctcP+N25zb+Xli9VWX46Y7+9tsoGywGnIg4p9K5QTM+c388i0mC0JBSLaFS2pZBRdR49hsLQ==</value>
</masterKey>
</descriptor>
</descriptor>
</key>
如您所见,文件相对简单.它说明了创建,激活,到期日期,使用的算法,对反序列化器类的引用,当然还有密钥本身.
As you see, file is relatively simple. It states creation, activation, expiration dates, algorithms used, reference to deserializer class and of course key itself.
现在我像这样配置asp.net应用程序(因此,是另一个应用程序,而不是该控制台的应用程序):
Now I configured asp.net application (so, another application, not that console one) like this:
services.AddDataProtection()
.SetApplicationName("my-app")
.PersistKeysToFileSystem(new DirectoryInfo(@"G:\tmp\so\keys-asp"))
.DisableAutomaticKeyGeneration();
如果现在尝试运行应用程序并执行需要保护的操作-它将失败,因为没有密钥,并且自动密钥生成被禁用.但是,如果我将控制台应用程序生成的密钥复制到目标文件夹中,它将 愉快地使用它们.
If you now try to run application and do something that requires protection - it will fail, because there no keys and automatic key generation is disabled. However, if I copy keys generated by console app to the target folder - it will happily use them.
因此,请注意与复制密钥有关的通常的安全问题,要注意这些密钥的过期时间(可使用SetDefaultKeyLifetime
配置),并在共享密钥的所有应用程序中使用相同版本的Microsoft.AspNetCore.DataProtection
与(因为它的版本是在关键xml文件中指定的)-您应该没问题.最好在一个地方生成您的共享密钥,在所有其他地方设置DisableAutomaticKeyGeneration
.
So pay attention to the usual security concerns with copying keys, to expiration time of those keys (configurable with SetDefaultKeyLifetime
) and using the same version of Microsoft.AspNetCore.DataProtection
in all applications you share keys with (because it's version is specified in key xml file) - and you should be fine. It's better to generate your shared keys in one place and in all other places set DisableAutomaticKeyGeneration
.
这篇关于.Net核心机器密钥替代Webfarm的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!