.Net Core Machine webfarm的关键替代方案

时间:2017-04-10 14:36:58

标签: c# linux docker .net-core machinekey

我一直在使用dotnet core来创建在Linux主机上的Kubernetes集群中运行的应用程序。在我测试时,它注意到在验证CSRF令牌时遇到异常,这是有道理的,因为我没有编辑机器密钥在每个实例上都是相同的。当我继续在web.config中设置机器密钥时,我注意到它将不再适用于.Net Core。

现在使用DataProtection API,机器密钥不再有效。我尝试将api实现到我的应用程序中,但是当我阅读时,我需要使用网络共享来交换所有实例之间的密钥我被震惊了。当然,必须有一种更简单(更好)的方法来实现这一目标,而不必依赖股票在线吗?

我尝试在ConfigureServices方法的Startup类中设置以下内容:

services.AddDataProtection().SetApplicationName("DockerTestApplication");

我以某种方式期望使用applicationname生成密钥,但这并没有解决问题。

我发现一些有趣的文档都使用了不再编译的代码,我猜微软改变了一些东西:

https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/compatibility/replacing-machinekey

有没有人知道这个问题的解决方案,它也可以在Linux上运行,并且能够在实例之间通过网络共享令牌?

提前致谢!

1 个答案:

答案 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