2011-11-17 5 views
16

Ho seguito questo tutorial su come creare un servizio OData.Come immettere codice nella password per una stringa di connessione in un modello dati Entity ADO.Net

http://www.hanselman.com/blog/CreatingAnODataAPIForStackOverflowIncludingXMLAndJSONIn30Minutes.aspx

e funziona senza problemi ... ma, nel modello entità guidata dei dati, quando si chiede di "Scegli la connessione dati" ti dà questo avvertimento.

"Questa stringa di connessione sembra contenere dati sensibili (ad esempio, una password) necessari per connettersi al database. La memorizzazione di dati sensibili nella stringa di connessione può rappresentare un rischio per la sicurezza. Si desidera includere questi dati sensibili nella stringa di connessione? "

Se scelgo: "No, esclude i dati sensibili dalla stringa di connessione. Lo imposterò nel mio codice applicazione".

Non vedo dove posso, "nel mio codice applicazione" inserire la password. (La mia azienda li memorizza cifrati nel registro)

Inoltre, ho più DB a cui ho bisogno di connettermi, a seconda dell'ambiente (Dev, CA o Prod) e ho bisogno di sapere a quale DB si fa riferimento nel stringa di connessione per ottenere la password corretta.

Grazie.

+0

Come * nel codice .. *, una bella formulazione della domanda:) – Irfan

risposta

27

Quando si crea il contesto, è possibile impostare una stringa di connessione. Per creare questa stringa di connessione, è possibile analizzare la stringa di connessione senza la password con uno EntityConnectionStringBuilder e quindi analizzare la stringa di connessione interna con un altro ConnectionStringBuilder, a seconda del browser. Quindi puoi impostare la password e passarla al costruttore.

var originalConnectionString = ConfigurationManager.ConnectionStrings["your_connection_string"].ConnectionString; 
var entityBuilder = new EntityConnectionStringBuilder(originalConnectionString); 
var factory = DbProviderFactories.GetFactory(entityBuilder.Provider); 
var providerBuilder = factory.CreateConnectionStringBuilder(); 

providerBuilder.ConnectionString = entityBuilder.ProviderConnectionString; 

providerBuilder.Add("Password", "Password123"); 

entityBuilder.ProviderConnectionString = providerBuilder.ToString(); 

using (var context = new YourContext(entityBuilder.ToString())) 
{ 
    // TODO 
} 
+2

Grazie! L'unico pezzo che non ha reso questo "plug-and-play" è stato dove mettere questo codice.Ho finalmente capito che avevo bisogno di sovrascrivere il DataService CreateDataSource() – saunderl

+2

Quando si esegue l'override del DataService CreateDataSource(), sarebbe pubblico o privato? –

9

Modificare il costruttore delle entità

public sampleDBEntities() : base("name=sampleDBEntities") 
    { 
     this.Database.Connection.ConnectionString = @"Data Source=.\;Initial Catalog=sampleDB;Persist Security Info=True;User ID=sa;Password=Password123"; ; 
    } 
3

La mia applicazione di esempio è stato scritto in "Database First" modalità e il metodo "CreateNewConnectionString" sotto funziona bene (anche se non sembra tutto ciò che elegante.)

Il metodo "CreateNewConnectionString2" sembra davvero elegante, MA causa un'eccezione che mi dice che è valido solo in modalità "Code First".

Quindi sto fornendo entrambi i metodi insieme al costruttore che ho modificato per utilizzare i miei metodi. NOTA E ATTENZIONE, ho modificato il codice generato da un modello e che è soggetto a essere sovrascritto se il codice viene rigenerato. A me sembra il posto giusto per dirlo.

Se l'applicazione è stata generata in modalità "Codice First", potrebbe essere necessario utilizzare "CreateNewConnectionString2" (non ho ancora testato questa opzione.)

mi affretto ad ammettere che ho copiato entrambi i blocchi di codice da altri post come non so ancora abbastanza su tutto questo per scrivere il mio codice.

private static string CreateNewConnectionString(string connectionName, string password) 
     { 
     var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~").ConnectionStrings.ConnectionStrings[connectionName]; 
     //or: 
     //var config = ConfigurationManager.ConnectionStrings[connectionName]; 
     var split = config.ConnectionString.Split(Convert.ToChar(";")); 
     var sb = new System.Text.StringBuilder(); 

     for (var i = 0; i <= (split.Length - 1); i++) 
     { 
      if (split[i].ToLower().Contains("user id")) 
      { 
       split[i] += ";Password=" + password; 
      } 

      if (i < (split.Length - 1)) 
      { 
       sb.AppendFormat("{0};", split[i]); 
      } 
      else 
      { 
       sb.Append(split[i]); 
      } 
     } 
     return sb.ToString(); 
    } 

    private static string CreateNewConnectionString2(string connectionName, string password) 
    { 
     var originalConnectionString = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString; 
     var entityBuilder = new EntityConnectionStringBuilder(originalConnectionString); 
     var factory = DbProviderFactories.GetFactory(entityBuilder.Provider); 
     var providerBuilder = factory.CreateConnectionStringBuilder(); 

     providerBuilder.ConnectionString = entityBuilder.ProviderConnectionString; 

     providerBuilder.Add("Password", password); 

     entityBuilder.ProviderConnectionString = providerBuilder.ToString(); 
     return entityBuilder.ProviderConnectionString; 
    } 

    public ChineseStudyEntities() 
     : base(CreateNewConnectionString("ChineseStudyEntities", "put YOUR password here")) // base("name=ChineseStudyEntities") 
    { 
    } 
7

ho aggiunto una password "fittizia" nel file di configurazione ("XXXXX"), poi sostituito tale valore con la password reale nel soggetto costruttore

public MyDatabaseContainer() : base("name=MyDatabaseContainer") 
{ 
    Database.Connection.ConnectionString = Database.Connection.ConnectionString.Replace("XXXXX","realpwd"); 
}