3
votes

I've been looking through several examples of encrypting connectionStrings (Web.config) in an ASP.NET MVC application (.NET 4.0) and it seems that there are two general ways to achieve it (example 1 and the related example 2):

Use the aspnet_regiis tool.

The main issue with using aspnet_regiis is that I can run the tool locally (on my development machine), but the web site actually hosted on Arvixe and like any other web host: there is no way to run commands on the server. As far as I understand, if I encrypt the Web.config connectionStrings on my machine and publish the Web.config, then they can't be decrypted on the server (please correct me if this is wrong).

Note: I only used the RSAProtectedConfigurationProvider, but I assume that the DataProtectionConfigurationProvider will have the same issue since it's user/machine specific.

Programatically encrypt the connection string.

Programmatically encrypting the connectionStrings also has a drawback: every time I publish my web site the Web.config is updated (with the unencrypted connectionStrings) and this means that for some period of time the Web.config will not be encrypted. Even if I ensure that the Web.config is only published when there are changes to it, the issue may be minimized but not mitigated.

I thought that using a static class may further help reduce the time connectionStrings are not encrypted. Unfortunately, encrypting the connectionStrings requires the application path and it seems that the only way to get the app path is from the request (Request.ApplicationPath) and in a static class there is (obviously) no request.

private void ProtectSection(string sectionName,
                                   string provider)
{
    Configuration config =
        WebConfigurationManager.
            OpenWebConfiguration(Request.ApplicationPath);

    ConfigurationSection section =
                 config.GetSection(sectionName);

    if (section != null &&
              !section.SectionInformation.IsProtected)
    {
        section.SectionInformation.ProtectSection(provider);
        config.Save();
    }
}

private void UnProtectSection(string sectionName)
{
    Configuration config =
        WebConfigurationManager.
            OpenWebConfiguration(Request.ApplicationPath);

    ConfigurationSection section =
              config.GetSection(sectionName);

    if (section != null &&
          section.SectionInformation.IsProtected)
    {
        section.SectionInformation.UnprotectSection();
        config.Save();
    }
}

UnProtectSection("appSettings");

ProtectSection("appSettings",
    "DataProtectionConfigurationProvider");

What's the proper way to encrypt the connectionString and eliminate/reduce the amount of time the Web.config section is not encrypted? Do you write some type of a wrapper around the OpenWebConfiguration method which check if the section is encrypted and only use that wrapper? Users may access any page on your web site, so how do you delay the encryption until they request some data from a database or do you check if it's encrypted at the first opportunity?

3
take a look to this post I think is something similar stackoverflow.com/questions/4197461/…JAiro
@JAiro, it is similar, but it still looks like it has the same problem: the protection configuration provider is not transferable to the host of the web site (as far as I understand)...Kiril

3 Answers

3
votes

The easiest way with the shared hoster is probably going to be to write your own encrypt/decrypt utility and store the connection string either in app settings, custom XML file, or text file, so that you have full control over the encryption/decryption process...

Per your update, you can get the current request via:

new HttpRequestWrapper(System.Web.HttpContext.Current.Request);

HTH.

0
votes

I've come up with a solution of my own, but I'm hoping that there is a better way to do it:

internal static class SecurityExtension
{
    public static string GetConnetionString(this Configuration config, string databaseName, string provider = "RSAProtectedConfigurationProvider")
    {
        string sectionName = "connectionStrings";
        ConfigurationSection section = config.GetSection(sectionName);
        if (section != null && !section.SectionInformation.IsProtected)
        {
            section.SectionInformation.ProtectSection(provider);
            config.Save();
        }

        return WebConfigurationManager.ConnectionStrings[databaseName].ConnectionString;
    }
}

Now I just have to use the extension every time I want to get the configuration string:

Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
string connectionString = config.GetConnetionString("MyDatabaseName");

Update:
Thanks to Brian, we can statically get the connection string:

private static HttpRequestWrapper request = new HttpRequestWrapper(System.Web.HttpContext.Current.Request);
private static Configuration config = WebConfigurationManager.OpenWebConfiguration(request.ApplicationPath);
private static string connectionString = config.GetConnetionString("MyDatabaseName"));

Of course you would not want to store the connection string like that, instead you would just use it to initialize your DataContext or use it for whatever else you need.

-1
votes

Get ConnectionString from Web.config File

Before starting how to read or get connectionstring from web.config file, you should know how to get connection string to connect your database from here that will show you also the difference why I’ve not used user id and password in my connection string. After knowing that, you can adjust your connection string in web.config as follows.

<connectionStrings>
   <add name="myDbConnection" providerName="System.Data.SqlClient"
   connectionString="Data Source=myServer;Integrated Security=true;Initial Catalog=myDatabase"/>
</connectionStrings>

To read or get connectionstring from web.config file in asp.net, we need to add System.Configuration namespace that will help us to read our connection string.

Note: If you have defined your connection string under appSettings section, you can get your connectionstring from appSettings section this way. Read Connectionstring in C#

protected void Page_Load(object sender, EventArgs e)
{
       string con = System.Configuration.ConfigurationManager.ConnectionStrings["myDbConnection"].ConnectionString;
}

Read Connectionstring in Vb.net

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
       Dim con As String = System.Configuration.ConfigurationManager.ConnectionStrings("myDbConnection").ConnectionString
End Sub

Example: Simple Insert, Update and Delete in Asp.net You may also like insert, update and delete on asp.net gridview here. That’s it, now you’ll be able get connectionstring from web.config file and can use wherever you want.

You can read more on asp.net via http://www.aspneto.com/category/aspnet/