本文介绍了.Net Core Machine Key 替代 webfarm的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用 dotnet core 创建一个在 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.

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

I found some interesting docs that all use code that will no longer compile, i guess Microsoft changed up some things:

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

有没有人知道这个问题的解决方案,它也可以在 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:	mpsokeys"));
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:	mpsokeys-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 willhappily 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 Core Machine Key 替代 webfarm的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-26 13:48