web-dev-qa-db-ja.com

Webfarmの.Net Core Machine Keyの代替

私は、dotnetコアを使用して、Linuxホスト上のKubernetesクラスターで実行されるアプリケーションを作成しています。テスト中、CSRFトークンの検証時に例外が発生することに気づきました。これは、すべてのインスタンスでマシンキーがまだ同じになるように編集していないため、理にかなっています。 web.configでマシンキーの設定に進むと、これが.Net Coreでは機能しないことに気付きました。

現在DataProtection APIを使用しているため、マシンキーは機能しなくなりました。私は自分のアプリケーションにAPIを実装しようとしましたが、読んだとき、すべてのインスタンス間でキーを交換するためにネットワーク共有を使用する必要があると思いました。確かに、共有をオンラインにするために頼る必要なく、これを達成するためのより簡単な(そしてより良い)方法がなければなりませんか?

configureServicesメソッドのStartupクラスに以下を設定しようとしました:

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

どういうわけか、アプリケーション名を使用してキーが生成されることを期待していましたが、これで問題は解決しませんでした。

私はすべてがもはやコンパイルされないコードを使用するいくつかの興味深いドキュメントを見つけました、私はMicrosoftがいくつかのことを変更したと思います:

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

Linuxでも実行され、インスタンス間でネットワークを介してトークンを共有できるこの問題の解決策を知っている人はいますか?

前もって感謝します!

16
WillemdeKok

キーのコピーに関するコメントをバックアップするために、いくつかのテストを行いました。まず、次のコードを使用して簡単なコンソールアプリケーションを作成しました。

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ファイルで指定されているため)とキーを共有します。 1つの場所で共有キーを生成し、他のすべての場所でDisableAutomaticKeyGenerationを設定することをお勧めします。

13
Evk