【问题标题】:How to securely store Connection String details in VBA如何在 VBA 中安全地存储连接字符串详细信息
【发布时间】:2011-03-14 02:52:59
【问题描述】:

我有一个 Excel 模板,它在 VBA 代码中硬编码 Ms Access MDB 路径,用于连接到 Access 表并保存、检索数据。

我将 MS Access 数据库迁移到 SQL Server,并为 Excel 模板用户提供集成身份验证。

我的问题是,存储 SQL Server DB 连接字符串并在 Excel 2007 VBA 中检索它以保存和检索数据的推荐方式/最佳实践是什么?

过去,我做过以下事情。

  1. 使用具有连接字符串的注册表项设置。然后在VBA中,编写一个读取注册表项并返回连接字符串的函数。

  2. 在 Excel 模板中有一个“设置”隐藏表,其中包含用于连接字符串的命名单元格。通过访问该命名范围来读取 VBA 中的连接字符串。

  3. 使用 Excel 模板附带的 .INI txt 文件。 (这并不理想,我想避免这种情况,因为它会依赖该外部文件)

我不喜欢#1,因为我想尽可能避免写入/读取注册表。 # 2 感觉还可以,我想我不确定是否有更好的“更清洁”的方式来做到这一点。

有什么想法吗?

【问题讨论】:

  • 查看我对线程stackoverflow.com/questions/1987333/…的回答
  • @Remou。谢谢。 @迈克D。谢谢,我查过了。虽然正在使用注册表,但我试图避免这种情况。因为在使用注册表设置时对产品问题进行故障排除将成为一场噩梦(因为它将是用户机器特定的设置)......
  • 我发现注册表是一个很好的地方,但这确实需要为每个用户进行额外的设置。我能理解你为什么要避免这种情况。

标签: vba connection-string


【解决方案1】:

这就是我安全存储连接字符串凭据的方法

下载安装Visual Studio Express 2012 for Windows (FREE)

以管理员身份打开并创建一个新项目。选择 Visual C# 然后选择 Class Library 并将其重命名为 HiddenConnectionString

Solution Explorer中,将Class1.cs重命名为MyServer.cs

Solution Explorer 中右键单击您的 MyConnection 项目并选择 Add Reference

在搜索框中输入activeX并勾选Microsoft ActiveX Data Objects 6.1 Library

将以下代码复制并粘贴到 MyServer.cs 中,完全替换文件中的任何内容。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.IO;
using ADODB;

namespace HiddenConnectionString
{
    [InterfaceType(ComInterfaceType.InterfaceIsDual),
    Guid("2FCEF713-CD2E-4ACB-A9CE-E57E7F51E72E")]
    public interface IMyServer
    {
        Connection GetConnection();
        void Shutdown();
    }

    [ClassInterface(ClassInterfaceType.None)]
    [Guid("57BBEC44-C6E6-4E14-989A-B6DB7CF6FBEB")]
    public class MyServer : IMyServer
    {
        private Connection cn;

        private string cnStr = "Provider=SQLOLEDB; Data Source=SERVER\\INSTANCE; Initial Catalog=default_catalog; User ID=your_username; Password=your_password";

        public MyServer()
        {
        }

        public Connection GetConnection()
        {
            cn = new Connection();
            cn.ConnectionString = cnStr;
            cn.Open();
            return cn;
        }

        public void Shutdown()
        {
            cn.Close();
        }
    }
}

在代码中找到cnStr 变量并更新您的连接字符串详细信息。

解决方案资源管理器中右键单击*HiddenConnectionString* 解决方案并选择属性。

点击左侧的Application标签,然后点击Assembly Info并勾选Make Assembly COM-Visible

点击左侧菜单中的*Build*并勾选Register For COM Interop

注意:如果您正在开发 64 位 Office,请确保将 Build 菜单上的 Platform Target 更改为 x64!这对于 64 位 Office COM 库是必需的,以避免任何与 ActiveX 相关的错误。


解决方案资源管理器中右键单击HiddenConnectionString,然后从菜单中选择Build

如果一切顺利,那么您的HiddenConnectionString.dllHiddenConnectionString.tlb 应该会成功生成。现在就去这条路

C:\Users\administrator\Documents\Visual Studio 2012\Projects\HiddenConnectionString\HiddenConnectionString\bin\Debug

你应该会看到你的文件。


现在打开 Excel 并转到 VBE。点击Tools并选择References

单击浏览按钮并导航到HiddenConnectionString.tlb

另外,添加对Microsoft ActiveX Object 6.1 Library 的引用 - 这样您就可以使用 ADODB 库了。

现在右键单击Project Explorer窗口中的任意位置并插入一个新的Module

复制并粘贴下面的代码

Option Explicit

Sub Main()

    Dim myCn As MyServer
    Set myCn = New MyServer

    Dim rs As ADODB.Recordset
    Set rs = New ADODB.Recordset

    rs.Open "Select * from [TABLE_NAME]", myCn.GetConnection

    Range("A1").CopyFromRecordset rs

    rs.Close
    myCn.Shutdown

    Set rs = Nothing
    Set myCn = Nothing

    Columns.AutoFit

End Sub

[TABLE_NAME] 替换为数据库中的实际表名。

点击 F5 或点击功能区上的绿色 播放 按钮。

如果一切正常,您现在应该会在电子表格中看到返回的表格。

我的样本:


如您所见。添加对您自己的 COM 库的引用并将登录凭据和其他敏感数据存储在已编译的 .dll 中可以保护您的数据(连接字符串)。反编译*.dll 文件以从中获取任何有意义的信息非常困难。有多种编码技术可以进一步保护您的*.dll,但我现在不打算详细介绍。这本身就达到了您的要求。

myCn.GetConnection 返回在引用的 COM 库中初始化的 ADODB.Connection 对象。不会向 Excel 用户显示连接字符串或敏感数据(实际上其他人也不会)。

您可以修改 C# 代码以接受来自 VBA 的参数,即登录名、密码、初始目录、要执行的查询等...如果您的 SQL Server 实例上的用户具有不同的权限,那也不错允许人们登录的想法。


注意:C# 代码和 VBA 中没有添加错误处理。如果您打算使用我上面描述的技术,我强烈建议您使用它。


【讨论】:

  • “我也在我的博客上发布了这个答案” - 已收藏!感谢您在这些类型的线程中做出的惊人贡献。
  • @mehow 感谢您的详细回答。如您所见,这是 3 年前的事了,我不再为那个项目或客户工作,但我仍然接受了您的回答。看起来它会起作用。
  • @Shiva 谢谢。无论如何,我决定给出这个答案,因为我自己在某个时间点找不到答案。希望它能很好地服务于其他人:)
  • @Yiping 这取决于您如何设置整个环境。通常,您可能只允许某些域用户能够与您的 SQL/任何服务器建立连接,不是吗?如果您使用 Windows 身份验证/或按用户身份验证,您可能甚至不需要隐藏连接字符串,因为您不需要用户名和密码...
  • 对不起,这仍然只是安全的假象。事实上,它更容易进入你的数据库,因为你可以引用你的 COM 对象并使用 that 来获得你自己的原始连接。
【解决方案2】:

将其存储在CustomDocumentProperties 下如何?

注意:我不确定,工作簿(基于给定模板)是否会继承模板中使用 CustomDocumentProperties 定义的属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多