views:

1646

answers:

7

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 have tried the following but am told that the configuration file is readonly.

ConfigurationManager.ConnectionStrings.Add(new ConnectionStringSettings(params));

Is there another way to do this at runtime? I know at design time I can add a connection string to the web.config; however, I'm looking to add something to that collection at run time.

Thanks

EDIT: One of the reasons why I'm attempting to do this is due to a security requirement that prevents me from placing ConnectionStrings in the web.config (even encrypted). I would like to use elements like Membership and Profiles on my project; however, I am looking into an alternative to doing such w/o writing a custom provider. Custom Provider's aren't all that bad, but if I can find an easier solution, I'm all for it.

A: 

No, you can't modify the config file at runtime, it isn't intended for that. Maybe you could use the Enterprise Libraries Configuration to do that.

ema
+2  A: 

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.

joshperry
+1  A: 
var cfg = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(@"/");
cfg.ConnectionStrings.ConnectionStrings.Add(new ConnectionStringSettings(params));

cfg.Save();

Be Advised this will cause your website to recycle since it modifies the config file. Check out http://msdn.microsoft.com/en-us/library/4c2kcht0(VS.80).aspx

JoshBerke
A: 

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" ... />
daughtkom
I just tried it and got the same read only error.
JamesEggers
+2  A: 

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.

Chris Marisic
I've tried on this one. That particular requirement came from the team in charge of DMZ security and doesn't want to risk having it exposed in case of a machine breech...even in an encrypted state since they would have the machine key at that point in a worst case scenario as well.
JamesEggers
Hmm if they have breached that box, they'll find your SQL server soon enough...you have to have the connection string on the server in some form or another...this is a silly requirement
JoshBerke
I fully agree with Josh, once they root your webserver your database will be soon to follow. This is protected by proper intrusion detection systems that you have a change to disable your servers which is at that point the only fool proof solution to the database being compromised.
Chris Marisic
I feel your pain, but the credentials of the ASP.NET user needs to have the right to whatever method your code uses to get the connection string. So even if your custom code is getting the connection string from a remote server or via some webservice, the hacker will be able to use the same method.
joshperry
+1  A: 

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"
joshperry
A: 

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.

Kibbee