2013-08-26 6 views
6

IISホストASP.NET MVC 4ウェブサイトの実行時にコード内でコードを動的に調整したい。ASP.NETマシンキーセットコード

使用するマシンキー、暗号化キー、検証キー、およびアルゴリズムは、データベースに格納されます。 web.configファイルから値を読み取るのではなく、アプリケーションの起動時にこれらの値を注入し、代わりにそれらの値を使用させたいと思います。

web.configを変更しなくても実現できる方法はありますか(メモリ構成を変更するだけです)。

設定セクションにアクセスしようとしましたが、読み取り専用とマークされており、封印されているため、IsReadOnly()を上書きすることはできません。しかし、があります。私には、readonlyフラグを削除する方法があるかもしれません。

var configSection = (MachineKeySection)ConfigurationManager.GetSection("system.web/machineKey"); 
if (!configSection.IsReadOnly()) 
{ 
     configSection.ValidationKey = _platformInfo.MachineKey.ValidationKey; 
     configSection.DecryptionKey = _platformInfo.MachineKey.EncryptionKey; 
     ... 
} 

これを達成する方法はありますか? 私が見ることのできる唯一の選択肢は、AppHarborのようなカスタムメソッドを使用することですが、可能であれば組み込みのアプローチに固執します。

誰かがなぜ私がそれをしたいのかと尋ねる場合、理由は、 これはウェブファームで実行されている多数の同一のウェブサイトのためのものです。したがって、非自動生成キーを持つことは必須です(各サーバーで同じである必要があります)。また、各ウェブサイトは隔離されていて、同じキーを共有すべきではありません。すべてのウェブサイトは物理的表現が同一なので、同じ物理的な場所を共有しています。これがweb.configファイルにアプリケーション固有の設定を含めることができない理由です。

編集:少なくとも単純には不可能であるかどうかを確認することは非常に役に立ちます。前述したように、カスタム認証と暗号化方式を使用することで、マシンキー設定を完全に使用することを避けることができます。ありがとう。

答えて

5

Webアプリケーションの起動後にこれをプログラムで設定する方法はありません。しかし、あなたの目標を達成することはまだ可能です。

各アプリケーションは、独自のアプリケーションプールで実行されている、各アプリケーションプールは、独自のアイデンティティを持っている場合は、applicationHost.configCLRConfigFileスイッチをチェックアウトしている場合。このアプリケーションごとのプールを使用して、新しいレベルの構成を注入できます。これを使用する方法の例については、http://weblogs.asp.net/owscott/archive/2011/12/01/setting-an-aspnet-config-file-per-application-pool.aspxを参照してください。明示的で一意の<system.web/machineKey>要素を各アプリケーションプールのカスタムCLR設定ファイルに設定できます。

これは、Azure Webサイト、GoDaddy、およびアプリケーションごとにデフォルトの明示的なマシンキーを設定する必要がある他のホストで使用されているのと同じメカニズムです。アクセスするアプリケーションプールに対して、それぞれのターゲット.configファイルを適切にACLすることを忘れないでください。

+0

おかげで私を助け多く、(とうまくいけば他の人も同様です)。通常、より大きなウェブサイトでは、別々のアプリケーションプールを使用しています。しかし、小規模なサイトは潜在的にアプリケーションプールを共有しています。しかし、私が必要としているのは、その周りに構築できるからです。 – michael81

+0

カスタムCLR設定ファイルの構造を "/configuration/system.web/machineKey"にする必要がありますか?アプリケーションで実際のmachineKey値を表示またはテストして、カスタムCLR設定ファイルが実際に正しく機能したかどうかを確認する方法はありますか? – John

+0

はい。 ConfigurationManager.GetSection( "system.web/machineKey")を使用して、返されたオブジェクトをMachineKeySectionにキャストし、そのプロパティを調べて変更が正しく取得されたことを確認できます。 – Levi

2

それは醜いですが、私は一時的にconfigセクションからの読み取り専用のビットを削除するためにリフレクションを使用することができた、キーを設定し、それを復元:

var getter = typeof(MachineKeySection).GetMethod("GetApplicationConfig", BindingFlags.Static | BindingFlags.NonPublic); 
var config = (MachineKeySection)getter.Invoke(null, Array.Empty<object>()); 

var readOnlyField = typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); 
readOnlyField.SetValue(config, false); 

config.DecryptionKey = myKeys.EncryptionKey; 
config.ValidationKey = myKeys.ValidationKey; 

readOnlyField.SetValue(config, true);