2017-04-10 49 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