So in my web app I want to store an ID and password, and I want to encrypt these keys to secure them. But there are other settings I want to leave in clear text to make for easier editing for my admins, and less web page work for me. The answer - custom sections inside my ASP.Net 2.0 web.config.
Good stuff! But as usual, it ain't straight forward. Here's what I ended up implementing. The web.config contains the following entry to create the new secured section:
Then inside my project I created the following class. It sets up the key/value pairs I needed inside my secure settings section of web.config.
Then, to use the class, easy peasy - just need to iterate through the pairs to find the key I need:
private string GetSecureConfigKey(string key)
{
String retval = "";
SecureConfiguration configInfo = (SecureConfiguration)ConfigurationManager.GetSection("secureSettings");
if (configInfo != null)
{
foreach (SecureConfigurationADKey secureKey in SecureConfiguration.GetConfig().ADKeys)
{
if (secureKey.Key.ToLower().Equals(key.ToLower()))
retval = secureKey.Value;
}
}
return retval;
}
To set the value, I needed to do something similar - but kept getting an error message that the configuration was read only. Huh?? Problem was I tried setting the value inside my foreach loop - tsk tsk. So instead I use the following:
Configuration objConfig = WebConfigurationManager.OpenWebConfiguration("~");
SecureConfiguration configInfo = objConfig.GetSection("secureSettings") as SecureConfiguration;
foreach (SecureConfigurationADKey secureKey in SecureConfiguration.GetConfig().ADKeys)
{
if (secureKey.Key.ToLower().Equals(Key.ToLower()))
{
index = i;
}
i++;
}
then
configInfo.ADKeys[index].Value = Value;
And all's well that ends well. Note too that I check the .IsProtected property of my section when I save the value:
if (!configInfo.SectionInformation.IsProtected)
{
configInfo.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
configInfo.SectionInformation.ForceSave = true;
}
and it works!
The class I use for the new web.config section follows:
public class SecureConfiguration : ConfigurationSection
{
public static SecureConfiguration GetConfig()
{
return ConfigurationManager.GetSection("secureSettings") as SecureConfiguration;
}
[ConfigurationProperty("adInfo")]
public SecureConfigurationADKeysCollection ADKeys
{
get
{
return this["adInfo"] as SecureConfigurationADKeysCollection;
}
set
{
this["adInfo"] = value;
}
}
}
public class SecureConfigurationADKey : ConfigurationElement
{
[ConfigurationProperty("key", IsRequired = true)]
public string Key
{
get
{
return this["key"] as string;
}
set
{
this["key"] = value;
}
}
[ConfigurationProperty("value", IsRequired = true)]
public string Value
{
get
{
return this["value"] as string;
}
set
{
this["value"] = value;
}
}
}
public class SecureConfigurationADKeysCollection : ConfigurationElementCollection
{
public SecureConfigurationADKey this[int index]
{
get
{
return base.BaseGet(index) as SecureConfigurationADKey;
}
set
{
if (base.BaseGet(index) != null)
{
base.BaseRemoveAt(index);
}
this.BaseAdd(index, value);
}
}
protected override ConfigurationElement CreateNewElement()
{
return new SecureConfigurationADKey();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((SecureConfigurationADKey)element).Key;
}
}