Is there a way where I can add a connection string to the ConnectionStringCollection returned by the ConfigurationManager at runtime in an Asp.Net application?
I hav
You can use reflection to disable the private bReadOnly field (bad idea, etc.):
typeof(ConfigurationElementCollection)
.GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(ConfigurationManager.ConnectionStrings, false);
ConfigurationManager.ConnectionStrings.Add(new ConnectionStringSettings());
This is similar to the technique required to modify an existing connection string, and added as a comment there by Brian Rodgers.
The configuration infrastructure supports very robust encryption through the Windows DataProtection API wich uses a machine specific key to encrypt the configuration sections. This way it would not be possible to read the encrypted data anywhere but on the machine where it was encrypted.
This is the same API that is used for the Government compliant drive/folder encryption in Windows. Would this stand up to your companies security requirements?
Either manually or through your deployment automation you can execute this command to encrypt the connectionStrings section of your web.config for a specific web application.
aspnet_regiis -pe "connectionStrings" -app "/MyCoolWebApplication" -prov "DataProtectionConfigurationProvider"
If you are trying to edit the connection strings in your web.config at runtime take a look at WebConfigurationManager.
If you are just trying to modify the configuration at runtime to inject a connection string then you are out of luck. The ConfigurationManager object tree is meant to be a direct reflection of the configuration files, if you were able to change that the state would then be inconsistent.
I would recommend creating a simple facade class that you could use to retrieve your connection strings. This way you could have the facade return a connection string from your on the fly collection or if one doesn't exist then it could grab it from the ConfigurationManager.
class ConnectionStringProvider
{
Dictionary<string, System.Configuration.ConnectionStringSettings> _localStrings = new Dictionary<string, System.Configuration.ConnectionStringSettings>();
public void AddLocalConnectionString(string name, string connstring)
{
System.Configuration.ConnectionStringSettings cs = new System.Configuration.ConnectionStringSettings(name, connstring);
_localStrings.Add(name, cs);
}
public void RemoveLocalConnectionString(string name)
{
_localStrings.Remove(name);
}
public System.Configuration.ConnectionStringSettings this[string name] {
get
{
return _localStrings.ContainsKey(name) ? _localStrings[name] : System.Configuration.ConfigurationManager.ConnectionStrings[name];
}
}
}
Or you could always go quite a bit heavier and use something like the Enterprise Library Configuration Block.
If you are using MS SQL you can configure you web server to access the SQL Server via the windows authentication, so you never have to have any passwords at all in your webconfig, or even floating around in your application memory.
Haven't tried it yet, but perhaps you can alter the value of an existing connection string at runtime? For example, instead of:
ConfigurationManager.ConnectionStrings.Add(new ConnectionStringSettings(params));
Maybe you could do something like:
ConfigurationManager.ConnectionStrings["myconnection"].ConnectionString = "something";
If so, you could specify the connection string "variables" in config, but set them to false or empty connection strings:
<add name="myconnection" connectionString="SET AT RUNTIME" ... />
Just to point out whoever gave you the "security requirement" that you can't place the connection string in the web.config is an idiot. The web.config can never be accessed by anything other than your application or remote access to the server.
This sounds entirely like a requirements problem and should be solved there.