2014-11-14 1 views
0

Я использовал предложение Бена Клотье из своего совета по блогу управления блоком Office (http://blogs.office.com/2011/04/08/power-tip-improve-the-security-of-database-connections/), чтобы создать соединение с кеш-ключами без DSN, чтобы пользовательские UID и PWD не сохранялись или требовались несколько раз при работе в интерфейсе доступа , Попросите других это сделать? Если да, каким был ваш подход, когда вам нужно использовать ADO-соединение вместо DOA для доступа к SQL из Access через VBA? Как открыть соединение adodb без необходимости повторного ввода идентификатора пользователя и пароля или его поместить в код? (Я использую интерфейс Access 2013, сервер SQL 2008 R2, безопасность SQL Server) Спасибо заранее!Сохранение UID и PWD из строки соединения ADO в базе данных ODBC DSN-less и кэшированном соединении DAO?

Мой Сохраненная код подключения работает следующим образом:

Public Function InitConnect(strUserName As String, strPassword As String) As Boolean 
' Description: Is called in the application’s startup 
'    to ensure that Access has a cached connection 
'    for all other ODBC objects’ use. 

    Dim dbs As DAO.Database 
    Dim qdf As DAO.QueryDef 
    Dim rst As DAO.Recordset 
    Dim strConnection As String 


    strConnection = "ODBC;DRIVER=sql server;" & _ 
      "SERVER=******;" & _ 
      "APP=Microsoft Office 2010;" & _ 
      "DATABASE=******;" & _ 
      "Network=DBMSSOCN;" 

    Set dbs = DBEngine(0)(0) 
    Set qdf = dbs.CreateQueryDef("") 
    With qdf 
     .Connect = strConnection & _ 
      "UID=" & strUserName & ";" & _ 
      "PWD=" & strPassword & ";" 
     .SQL = "Select Current_User;" 

     Set rst = qdf.OpenRecordset(dbOpenSnapshot, dbSQLPassThrough) 

    End With 
    InitConnect = True 

ExitProcedure: 
    On Error Resume Next 
     Set rst = Nothing 
     Set qdf = Nothing 
     Set dbs = Nothing 
    Exit Function 
End Function 

Затем, когда мне нужно получить доступ к данным, я могу сделать это (обратите внимание на UID и PWD не требуется):

Dim dbs As DAO.Database 
Set dbs = OpenDatabase("", False, False, "ODBC;DRIVER=sql server;SERVER=*****;APP=Microsoft Office 2010;DATABASE=*****;Network=DBMSSOCN") 

я могу также установите соединение ODBC на сквозные запросы, а также в Access или VBA. Но эти соединения работают только тогда, когда строка соединения IDENTICAL соответствует тому, что первоначально использовалось в моем коде Cached Connection. Итак, когда мне нужно подключение ADODB (как кажется, иногда требуется ADO?), Строка, очевидно, не будет идентичной.
Для примера:

Dim cn As New ADODB.Connection 
cn.Open "Provider = sqloledb;Data Source=*same as "SERVER"*;Initial Catalog=*same as "DATABASE"*;User Id=****;Password=****" 

Этот тип подключения работает только если я поставить идентификатор пользователя и пароль. Как я могу написать это, чтобы они мне не нужны? ~ Спасибо!

+0

Лучший способ скрыть имя пользователя и пароль - не использовать имя пользователя и пароль :-) Если возможно, подумайте об использовании [надежного соединения] (http://stackoverflow.com/a/1250556/772086) (Проверка подлинности Windows). – Mike

+0

Я полностью согласен с Майком! Проблема в том, что я работаю удаленно из Висконсина, и у меня есть более 20 пользователей в штате Иллинойс, которые также работают как «работа», так и удаленно либо из дома, либо из рабочего компьютера на дороге. Таким образом, логистика сохранения всех этих протекционистских историй становится сложной. Кроме того, я всего лишь администратор базы данных для пары баз данных на сервере - люди выше меня не хотят иметь дело с управлением аутентификацией. – LauraNorth

+0

У меня может быть рабочее решение, но кто-нибудь видит опасность в этом подходе, прежде чем я ставил его в качестве ответа? Я создал две общедоступные переменные «strUID» и «strPWD», которые устанавливаются, когда пользователь нажимает мой экран входа (например, «strUID» Forms! FRM_login! TxtUserID »). Затем я ссылаюсь на них, когда мне нужно использовать строку соединения ADO. Я довольно новичок в этом мире кодирования, поэтому я просто не хочу нарушать безопасность моего пользователя при любых ошибках «новичка»! Спасибо всем! – LauraNorth

ответ

1

Хотя ACCESS имеет некоторые недостатки в отношении безопасности, вы можете сделать несколько вещей, чтобы минимизировать риски. Один из них будет скомпилировать БД для ACCDE. Таким образом, VBA компилируется и не отображается.

Вы можете создать публичную функцию, которая возвращает строку

Public Function GET_CONNECTION_STRING() as STRING 
' construct your connection string here with server name and password 
    GET_CONNECTION_STRING = "DRIVER={" & Driver & "};PORT=" & mPort & ";DATABASE=" & mDatabase & ";SERVER={" & mServer & "};UID=" & mUser & ";PWD={" & mPassword & "};" 
End Function 

затем создать макрос AutoExe, которая запускается при открытии приложения. в вашем AutoExe выполняет обновление ссылок на ваши связанные таблицы. что-то похожее на то, что у вас есть.

For Each tdf In db.TableDefs 
    If tdf.connect <> vbNullString Then 
     tdf.connect = GET_CONNECTION_STRING & ";TABLE=" & tdf.name 
     tdf.RefreshLink 
    End If 
Next tdf 

вы можете сделать то же самое для существующего прохода через запросы:

For Each myQuerydef In MyDB.QueryDefs 
    If Left(myQuerydef.connect, 4) = "ODBC" Then 
     myQuerydef.connect = "ODBC;" & GET_CONNECTION_STRING 
     myQuerydef.Close 
    End If 
    Next 

кроме того, вы можете иметь некоторые другие общественные функции, чтобы получить вошедшие в имени пользователя. что-то вроде

public function getCrruserID() as int 
    'check your public variable crr_user_id if its empty redirect to login 
    if nz(crr_user_id,0) = 0 then 
    'go to login and save the user id after successful login 
    else 
     getCrruserID = crr_user_id 
    end if 
end function 

использования простой DAO для выполнения SQL-код, как

dim db as DAO.Database 
set db = currentdb 
dim rs as Dao.Recordset 
set rs = db.openrecordset("select something from your linked table") 

или

db.execute "update command", dbfailonerror 

на ваш последний вопрос. если вы сохраните что-то в памяти, оно будет уничтожено после закрытия приложения.

EDIT: Если у вас более 50 связанных таблиц, это может быть нецелесообразно обновлять их при каждом запуске.Вместо этого вы можете создать локальную таблицу, содержащую ваши [local_Appversion, isFreshInstall] и некоторые другие переменные в соответствии с вашими потребностями. Каждый раз, когда ваш пользователь получает обновление, newInstall будет правдой и будет указывать ваше приложение для подключения и обновления всех таблиц. (чтобы убедиться, что клиент получит непрерывное соединение)

поэтому в вашем коде autoExe: если его freshInstall затем подключитесь и обновите ссылки, если не просто установите connectionString. (обычно это заставка после входа в систему для выполнения этого действия) После успешного подключения просто обновите значение local isFreshInstall до значения false для более быстрого запуска в следующий раз.

вы также можете иметь специальное меню, где пользователь может нажать и обновить ссылки вручную. (В случае, если соединение понижено) что-то вроде custom menu for access

, если ваша организация имеет домен, вы можете позволить доверенное соединение с помощью windows login name удачи.

+0

Спасибо, Криш! Я не знал о возможности компиляции в ACCDE - я обязательно буду принимать этот совет. Кажется, что если я это сделаю, то публичные переменные, которые я использую, не будут видны и будут уничтожены, когда приложение будет уничтожено. – LauraNorth

+0

Кроме того, по вашему предложению кода, это то, с чего я начал, прежде чем я прочитал блог Clothier's, упомянутый выше (см. Также http://stackoverflow.com/questions/23249865/how-to-link-and-odbc-table-to- MS-Access-базы данных с помощью-VB-и-без подключения/23252890 # 23252890). Я не знаю, лучше ли кто-то другой, но кажется, что не нужно снова связывать все, что было при входе в систему, возможно, быстрее. – LauraNorth

+0

@LauraNorth добавили еще несколько предложений в ответ на сообщение. –

Смежные вопросы