我一直在使用dotnet core来创建在Linux主机上的Kubernetes集群中运行的应用程序。在我测试时,它注意到在验证CSRF令牌时遇到异常,这是有道理的,因为我没有编辑机器密钥在每个实例上都是相同的。当我继续在web.config中设置机器密钥时,我注意到它将不再适用于.Net Core。
现在使用DataProtection API,机器密钥不再有效。我尝试将api实现到我的应用程序中,但是当我阅读时,我需要使用网络共享来交换所有实例之间的密钥我被震惊了。当然,必须有一种更简单(更好)的方法来实现这一目标,而不必依赖股票在线吗?
我尝试在ConfigureServices方法的Startup类中设置以下内容:
services.AddDataProtection().SetApplicationName("DockerTestApplication");
我以某种方式期望使用applicationname生成密钥,但这并没有解决问题。
我发现一些有趣的文档都使用了不再编译的代码,我猜微软改变了一些东西:
有没有人知道这个问题的解决方案,它也可以在Linux上运行,并且能够在实例之间通过网络共享令牌?
提前致谢!
答案 0 :(得分:13)
我已经做了一些测试来支持我关于复制密钥的评论。首先,我使用以下代码创建了简单的控制台应用程序:
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容器,在那里注册数据保护,使用特定的密钥文件夹,解决并保护内容。
这会在目标文件夹中生成以下密钥文件:
<?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>
如您所见,文件相对简单。它说明了创建,激活,到期日期,使用的算法,对反序列化器类的引用,当然还有密钥本身。
现在我配置了asp.net应用程序(所以,另一个应用程序,而不是那个控制台),如下所示:
services.AddDataProtection()
.SetApplicationName("my-app")
.PersistKeysToFileSystem(new DirectoryInfo(@"G:\tmp\so\keys-asp"))
.DisableAutomaticKeyGeneration();
如果您现在尝试运行应用程序并执行需要保护的操作 - 它将失败,因为没有密钥和自动密钥生成被禁用。但是,如果我将控制台应用程序生成的密钥复制到目标文件夹 - 它会 高兴地使用它们。
因此,请注意复制密钥的常见安全问题,这些密钥的到期时间(可使用SetDefaultKeyLifetime
配置)和使用相同版本的Microsoft.AspNetCore.DataProtection
你共享密钥的应用程序(因为它的密钥xml文件中指定了它的版本) - 你应该没问题。最好在一个地方和所有其他地方生成共享密钥DisableAutomaticKeyGeneration
。