从Web.config中读取自定义加密连接字符串

时间:2014-03-07 13:36:37

标签: c# asp.net encryption

我有一个现有的ASP.NET项目,其中通过在C#中使用自定义加密函数在Web.config文件中加密连接字符串,并将该加密字符串保存到Web.config文件中,如下所示......

<add name="ConnectionString" connectionString="+tj/H0V/Wpa+UBWzHvOfuL4GPyoDssypPKfeRdUU1FnfHw+phOEBLpRne/ytv1v8gs7P0DoSC7rhN2aPWG3uZZvSis5f/Dqu53HgsRH8m44=" providerName="System.Data.SqlClient" />

我现在想要使用需要SQLDataSource的控件向该项目添加一个Page,并且我已经在.aspx代码中指定了ConnectionString,作为SQLDataSource的属性,如下所示......

<asp:SqlDataSource ID="PeriodsDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>"

这显然现在正在尝试读取connectionString,但是获取加密字符串,并抛出错误......

  

“不支持关键字:   '+ TJ / h0v / WPA + ubwzhvoful4gpyodssyppkferduu1fnfhw + phoeblprne / ytv1v8gs7p0dosc7rhn2apwg3uzzvsis5f / dqu53hgsrh8m44'。“

如何将ConnectionString传递给我的自定义Encryption.Decrypt函数,以便SQLDataSource使用Un-Encrypted字符串?

我试过简单地将以下内容添加到Page_Load事件中,这有助于初始加载,但在回发后我仍然得到上面提到的错误。 (不,这不在!IsPostBack中)

string connectionString = Encryption.Decrypt(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString, "XXXXXX");
        PeriodsDataSource.ConnectionString = connectionString;

2 个答案:

答案 0 :(得分:1)

这是我已实施的解决方案。

%$ConnectionString的{​​{1}}字符是一个表达式,因此被求值。我们可以创建自己的自定义表达式。

像这样创建asp:SqlDataSource并扩展class

ExpressionBuilder

您已经在namespace YourNameSpace { [ExpressionPrefix("EncryptedExpressionStrings")] public class EncryptedConnectionStringExpressionBuilder : ExpressionBuilder { private static string DecryptConnectionString(string cipherText) { return Encryption.Decrypt(cipherText); } public static ConnectionStringSettings GetConnectionStringSettings(string connectionStringName) { return ConfigurationManager.ConnectionStrings[connectionStringName]; } public static string GetConnectionString(string connectionStringName) { string decryptedConnectionString = null; System.Web.Caching.Cache connectionStringCache = new System.Web.Caching.Cache(); if (connectionStringCache["connectionString"] == null) { ConnectionStringSettings settings = GetConnectionStringSettings(connectionStringName); decryptedConnectionString = DecryptConnectionString(settings.ConnectionString); connectionStringCache.Insert("connectionString", decryptedConnectionString); } else { decryptedConnectionString = (string)connectionStringCache["connectionString"]; } return decryptedConnectionString; } public static string GetConnectionStringProviderName(string connectionStringName) { ConnectionStringSettings settings = GetConnectionStringSettings(connectionStringName); return settings.ProviderName; } public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) { Pair pair = DirectCast<Pair>(parsedData); string text = pair.First.ToString(); if (Convert.ToBoolean(pair.Second)) { return new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(base.GetType()), "GetConnectionString", new CodeExpression[] { new CodePrimitiveExpression() { Value = text } }); } else { return new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(base.GetType()), "GetConnectionStringProviderName", new CodeExpression[] { new CodePrimitiveExpression() { Value = text } }); } static T DirectCast<T>(object o) where T : class { T value = o as T; if (value == null && o != null) { throw new InvalidCastException(); } return value; } }

中声明了新的自定义ExpressionBuilder
web.config

然后您声明已加密的connectionString

<compilation>
    <expressionBuilders>
        <add expressionPrefix="EncryptedExpressionStrings" type="YourNameSpace.EncryptedConnectionStringExpressionBuilder"/>
     </expressionBuilders>
</compilation>

然后,在web.config中为自定义<connectionStrings> <add name="EncryptedSqlDBConnectionString" connectionString="nWCfxsad8lkdyLWERODVxd3Ox..." </connectionStrings> 声明前缀的名称,并在ExpressionBuilder中声明ConnectionString的名称

asp:SqlDataSource

这意味着您可以在<asp:SqlDataSource runat="server" ID="YourID" ConnectionString="<%$ EncryptedExpressionStrings:EncryptedSqlDBConnectionString %>" SelectCommand="SELECT * FROM YourDBTable" /> 中加密连接字符串,并且仍然可以评估web.config asp.SqlDataSource

答案 1 :(得分:0)

事实证明,这是更新SqlDataSource的Init事件中SqlDataSource.ConnectionString的非常简单的解决方案,如下所示:

    protected void SqlDataSource_Init(object sender, EventArgs e)
    {
        string connectionString = Encryption.Decrypt(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString, "XXXXXX");
        SqlDataSource.ConnectionString = connectionString;
    }