2017-04-10 39 views
10

我一直在使用dotnet核心创建一个在Linux主机上的Kubernetes集群中运行的应用程序。当我测试它时发现在验证CSRF令牌时会出现异常,这是有道理的,因为我没有将机器密钥编辑为在每个实例上都一样。当我继续在web.config中设置机器密钥时,我注意到这将不再在.Net核心中工作。.Net核心机webfarm的关键替代方案

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

我试图设置在ConfigureServices方法启动类如下:

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

我有点预计使用的applicationName生成密钥,但这并没有解决问题。

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

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

有谁知道解决这个问题,也将在Linux上运行并且能够在实例之间共享网络上的令牌?

在此先感谢!

+0

在将机器密钥从一台机器复制到另一台机器之前,现在您可以以同样的方式复制这些密钥?虽然请注意,密钥有到期时间(默认90天),因此您应该增加密钥或创建自动刷新过程。 – Evk

+1

谢谢你的回答!我会尝试使用TeamCity文物自动化。令我惊讶的是,官方文档提到使用samba共享来交换这些密钥,因为这增加了单点故障并且通常比使用静态机器键更麻烦。我会尝试将密钥复制到网络服务器。 – WillemdeKok

回答

6

我做了一些测试来备份我对复制密钥的评论。首先,我创建了下面的代码简单的控制台应用程序:

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

+0

哇哇谢谢你!我一到办公室就会明天再试。自动化这将是比使用SMB共享更好的解决方案。 – WillemdeKok

+0

这件作品很有魅力,非常感谢!对于所有想要自己尝试此操作的人,请务必引用Microsoft.AspNetCore.DataProtection和Microsoft.AspNetCore.DataProtection.Extensions包。它可以在.Net核心和常规.Net控制台应用程序中运行。 – WillemdeKok

+0

@evk,是不是存储密钥到静态文件,其中IIS暴露给公众(我的意思是IIS_USR或应用程序池所有者应该有明确的访问权限来执行文件操作在指定的位置)的风险?? ?? – Jay