Как безопасно хранить информацию о строках соединения в VBA

У меня есть шаблон Excel, который имеет жестко запрограммированный путь MDB MDB в коде VBA, который используется для подключения к таблицам Access и сохранения, получения данных.

Я перенес базу данных MS Access на SQL Server со встроенной проверкой подлинности для пользователей шаблонов Excel.

Мой вопрос: что такое рекомендуемый способ/лучшая практика для хранения строки подключения к базе данных SQL Server и ее возврата в Excel 2007 VBA для сохранения и извлечения данных?

В прошлом я сделал следующее.

  • Используйте параметр реестра, в котором есть строка подключения. Затем в VBA напишите функцию, которая считывает ключ реестра и возвращает строку соединения.

  • У вас есть скрытый лист "Настройки" в шаблоне Excel с именованной ячейкой для строки подключения. Прочитайте строку соединения в VBA, обратившись к указанному диапазону.

  • Используйте txt файл .INI, который идет с шаблоном Excel. (Это не идеально, и я хочу избежать этого, поскольку он создает зависимость от этого внешнего файла)

Мне не нравится # 1, потому что я хочу, чтобы избежать записи в/чтение из реестра, если это возможно. # 2 чувствует себя хорошо, думал, что я не уверен, есть ли лучший "более чистый" способ для этого.

Любые мысли?

Ответ 1

Вот что я сделал бы безопасно хранить учетные данные строки подключения

Загрузите и установите Visual Studio Express 2012 для Windows (БЕСПЛАТНО)

Откройте его как Администратор и создайте новый проект. Выберите Visual C#, затем Class Library и переименуйте его в HiddenConnectionString

enter image description here

В обозревателе решений переименуйте Class1.cs в MyServer.cs

enter image description here

Щелкните правой кнопкой мыши ваш проект MyConnection в обозревателе решений и выберите Add Reference

Введите activeX в поле поиска и отметьте Microsoft ActiveX Data Objects 6.1 Library

enter image description here

Скопируйте и вставьте приведенный ниже код в 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

enter image description here

Нажмите *Build* в меню слева и отметьте Register For COM Interop

enter image description here

Примечание. Если вы разрабатываете для 64-битного Office, убедитесь, что вы изменили Platform Target в меню "Построение" на x64! Это необходимо для 64-битных библиотек Office COM, чтобы избежать ошибок, связанных с ActiveX.


Щелкните правой кнопкой мыши по HiddenConnectionString в обозревателе решений и выберите Build в меню.

Если все прошло нормально, ваши HiddenConnectionString.dll и HiddenConnectionString.tlb должны быть успешно сгенерированы. Перейти к этому пути сейчас

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

и вы должны увидеть свои файлы.

enter image description here


Теперь откройте Excel и перейдите в VBE. Нажмите Tools и выберите References.

Нажмите кнопку Browse и перейдите к HiddenConnectionString.tlb.

Также добавьте ссылки на Microsoft ActiveX Object 6.1 Library - это значит, что вы можете использовать библиотеку ADODB.

enter image description here

Теперь щелкните правой кнопкой мыши в любом месте окна 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 или нажмите зеленую кнопку воспроизведения на ленте.

enter image description here

Если все пошло хорошо, теперь вы должны увидеть возвращенную таблицу в своей таблице.

мой пример:

enter image description here


Как вы можете видеть. Добавление ссылок на вашу собственную COM-библиотеку и сохранение учетных данных входа и других конфиденциальных данных внутри скомпилированного .dll защищает ваши данные (строку подключения). Очень сложно декомпилировать файл *.dll, чтобы получить от него разумную информацию. Существуют различные методы кодирования, чтобы еще больше защитить ваш *.dll, но теперь я не буду вдаваться в подробности. Это само по себе достигает того, о чем вы просили.

myCn.GetConnection возвращает объект ADODB.Connection, который был инициализирован внутри указанной библиотеки COM. Никакой пользователь Excel не будет представлен строкой соединения или конфиденциальными данными (на самом деле ни у кого другого нет).

Вы можете изменить код С#, чтобы принимать параметры из VBA, т.е. логин, пароль, начальный каталог, запрос для выполнения и т.д.... если у вас есть пользователи с разными привилегиями на экземпляре вашего SQL Server, это не будет плохо идея позволить пользователям войти в систему.


Примечание: в коде С# и VBA нет обработки ошибок. Я бы настоятельно рекомендовал работать над этим, если вы планируете использовать технику, описанную выше.


Ответ 2

Как насчет сохранения в CustomDocumentProperties?

Примечание. Я не уверен, что если книга (на основе данного шаблона) наследует свойство, определенное с помощью CustomDocumentProperties в шаблоне.