2013-08-26 9 views
6

Desidero regolare dinamicamente le chiavi della macchina nel codice durante il runtime, per un sito Web ASP.NET MVC 4 ospitato da IIS.Tastiera ASP.NET set chiavi nel codice

Le chiavi della macchina, la crittografia e le chiavi di convalida, nonché gli algoritmi da utilizzare, sono memorizzati in un database. Invece di leggere i valori dal file web.config, voglio iniettare quei valori durante l'avvio dell'applicazione e lasciare che il sistema li usi.

Esiste un modo per farlo senza dover modificare web.config (per modificare solo la configurazione in memoria)?

Ho provato ad accedere alla sezione di configurazione ma è contrassegnato come readonly ed è anche sigillato, quindi non posso eseguire l'override di IsReadOnly(). Tuttavia, c'è un setter che è un indicatore, per me, che potrebbe esserci un modo per rimuovere potenzialmente il flag di sola lettura.

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

C'è qualche modo per realizzare questo? L'unica alternativa che posso vedere è l'utilizzo di un metodo personalizzato come AppHarbor, tuttavia preferisco attenermi all'approccio integrato, se è possibile.

Nel caso in cui qualcuno chieda perché voglio farlo, il motivo è, questo è per un gran numero di siti Web identici in esecuzione in una webfarm. Quindi, avere chiavi non generate automaticamente è un must (deve essere lo stesso su ciascun server). Inoltre ogni sito web dovrebbe essere isolato e non condividere le stesse chiavi. Poiché tutti i siti Web sono identici nella loro rappresentazione fisica, condividono la stessa posizione fisica. Questo è il motivo per cui il file web.config non può contenere impostazioni specifiche dell'applicazione.

Modifica: Sarebbe molto utile per confermare, almeno, se semplicemente non è possibile. Come detto, è possibile utilizzare metodi di autenticazione e crittografia personalizzati che eviterebbero di utilizzare completamente le impostazioni della chiave della macchina. Grazie.

risposta

5

Non è possibile impostarlo a livello di codice dopo l'avvio dell'applicazione Web. Tuttavia, è ancora possibile raggiungere il tuo obiettivo.

Se ogni applicazione è in esecuzione in un proprio pool di applicazioni, e se ogni pool di applicazioni ha una propria identità, quindi controllare l'interruttore CLRConfigFile in applicationHost.config. È possibile utilizzare questo pool di applicazioni per iniettare un nuovo livello di configurazione. Vedi http://weblogs.asp.net/owscott/archive/2011/12/01/setting-an-aspnet-config-file-per-application-pool.aspx per un esempio su come usarlo. È possibile impostare un elemento <system.web/machineKey> univoco e esplicito nel file di configurazione CLR personalizzato di ogni pool di applicazioni.

Questo è lo stesso meccanismo utilizzato da siti Web di Azure, GoDaddy e altri hosters che devono impostare chiavi macchina esplicite predefinite per applicazione. Ricordarsi di eseguire ACL ogni file .config di destinazione in modo appropriato per il pool di applicazioni che accederà ad esso.

+0

Grazie tante, che mi aiuta (e spero anche agli altri). Di solito i siti Web più grandi utilizzano pool di applicazioni separati. Ma siti più piccoli stanno potenzialmente condividendo un pool di applicazioni. Ma esattamente quello di cui ho bisogno, dato che posso costruirmi intorno. – michael81

+0

La struttura del file di configurazione CLR personalizzato deve essere "/configuration/system.web/machineKey"?Esiste un modo per visualizzare o verificare il valore effettivo della macchina sul file dell'applicazione per confermare che il file di configurazione CLR personalizzato abbia effettivamente avuto effetto? – John

+0

Sì. È possibile utilizzare ConfigurationManager.GetSection ("system.web/machineKey"), eseguire il cast dell'oggetto MachineKeySection e osservare le proprietà che ne dipendono per verificare che le modifiche siano state rilevate correttamente. – Levi

2

E 'brutto, ma sono stato in grado di utilizzare la reflection per rimuovere temporaneamente il bit di sola lettura dalla sezione di configurazione, impostare i tasti, quindi ripristinarlo:

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); 
Problemi correlati