2013-08-26 11 views
6

Chcę dynamicznie dopasowywać klucze komputera w kodzie podczas wykonywania, dla hostowanej w IIS witryny ASP.NET MVC 4.Zestaw kluczy maszyn ASP.NET w kodzie

Klucze maszynowe, klucze szyfrowania i sprawdzania poprawności oraz algorytmy używane są przechowywane w bazie danych. Zamiast czytać wartości z pliku web.config, chcę wprowadzić te wartości podczas uruchamiania aplikacji i pozwolić systemowi na ich użycie.

Czy istnieje sposób, aby to zrobić bez konieczności zmiany web.config w ogóle (aby zmienić tylko konfigurację pamięci)?

Próbowałem uzyskać dostęp do sekcji konfiguracji, ale jest oznaczony jako tylko do odczytu i jest również zaplombowany, więc nie mogę przesłonić IsReadOnly(). Jednak istnieje setter, który jest dla mnie wskaźnikiem, że może istnieć sposób potencjalnego usunięcia flagi readonly.

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

Czy jest jakiś sposób, aby to osiągnąć? Jedyną alternatywą jaką widzę jest użycie niestandardowej metody, takiej jak AppHarbor, jednak wolałbym trzymać się wbudowanego podejścia, jeśli jest to w ogóle możliwe.

Jeśli ktoś zapyta, dlaczego chcę to zrobić, powodem jest to, że jest to wiele identycznych stron internetowych działających w sieci web. Dlatego posiadanie kluczy nie wygenerowanych automatycznie jest koniecznością (musi być takie samo na każdym serwerze). Każda witryna powinna być odizolowana i nie powinna mieć tych samych kluczy. Ponieważ wszystkie witryny są identyczne pod względem fizycznej reprezentacji, mają tę samą fizyczną lokalizację. Z tego powodu plik web.config nie może zawierać ustawień specyficznych dla aplikacji.

Edycja: Bardzo pomocne byłoby potwierdzenie, przynajmniej jeśli jest to po prostu niemożliwe. Jak już wspomniano, można korzystać z niestandardowych metod uwierzytelniania i szyfrowania, które pozwoliłyby całkowicie uniknąć użycia ustawień klucza komputera. Dzięki.

Odpowiedz

5

Nie ma sposobu, aby ustawić to programowo po uruchomieniu aplikacji internetowej. Jednak nadal można osiągnąć swój cel.

Jeśli każda aplikacja jest uruchomiona we własnej puli aplikacji, a jeśli każda pula aplikacji ma swoją własną tożsamość, a następnie sprawdzić CLRConfigFile przełącznik w applicationHost.config. Możesz użyć tej puli dla poszczególnych aplikacji, aby wprowadzić nowy poziom konfiguracji. Zobacz http://weblogs.asp.net/owscott/archive/2011/12/01/setting-an-aspnet-config-file-per-application-pool.aspx, aby dowiedzieć się, jak tego użyć. Można ustawić jawny i unikalny element <system.web/machineKey> we niestandardowym pliku konfiguracyjnym CLR puli aplikacji.

Jest to ten sam mechanizm używany przez witryny sieci Web Azure, GoDaddy i inne hosty, które muszą ustawiać domyślne jawne klucze komputera dla poszczególnych aplikacji. Pamiętaj, aby odpowiednio dopasować każdy docelowy plik .config do puli aplikacji, która będzie uzyskiwać do niego dostęp.

+0

Wielkie dzięki, że mi pomaga (i mam nadzieję, że inni również). Zwykle większe witryny używają osobnych pul aplikacji. Jednak mniejsze witryny potencjalnie udostępniają pulę aplikacji. Ale dokładnie to, czego potrzebuję, ponieważ mogę to zbudować. – michael81

+0

Czy struktura niestandardowego pliku konfiguracyjnego CLR powinna być "/configuration/system.web/machineKey"?Czy istnieje sposób wyświetlenia lub przetestowania rzeczywistej wartości klucza MachineKey w aplikacji, aby potwierdzić, że niestandardowy plik konfiguracyjny CLR faktycznie przyjął skutek? – John

+0

Tak. Możesz użyć ConfigurationManager.GetSection ("system.web/machineKey"), przesłać zwrócony obiekt do MachineKeySection i sprawdzić właściwości wiszące z niego, aby sprawdzić, czy zmiany zostały poprawnie pobrane. – Levi

2

Jest brzydka, ale byłem w stanie wykorzystać odbicie tymczasowe usunięcie bitu tylko do odczytu z sekcji config ustawić klawisze, a następnie odtworzyć go:

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); 
Powiązane problemy