在无DNS无DSN数据库和DAO缓存连接中保持UID和PWD不在ADO连接字符串中?

时间:2014-11-14 05:16:15

标签: sql-server odbc access-vba ado

我使用Ben Clothier的Office Blog Power提示(http://blogs.office.com/2011/04/08/power-tip-improve-the-security-of-database-connections/)建议使用缓存凭据创建无DSN连接,以便用户的UID和PWD不会保存,或者需要多次保存在Access界面中工作。有其他人这样做了吗?如果是这样,当您需要使用ADO连接而不是DOA通过VBA从Access访问SQL时,您的方法是什么?如何打开adodb连接而无需再次提供用户ID和密码,或者必须将其放入代码中? (我正在使用Access 2013前端,SQL 2008 R2后端,SQL Server安全性) 提前谢谢!

我的缓存连接代码的工作方式如下:

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")

我还可以在Access或VBA中将ODBC连接设置为传递查询。但是,只有当连接字符串与我在缓存连接代码中最初使用的连接字符串相同时,这些连接才起作用。那么,当我需要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=****"

此类连接仅在我提供用户ID和密码时才有效。如何编写它以便我不需要它们? 〜谢谢!

1 个答案:

答案 0 :(得分:1)

虽然爱可信在安全性方面存在一些弱点,但您可以采取一些措施来降低风险。其中一个是将DB编译为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

到你的上一个问题。如果你在内存中保存了一些东西,它将在你的应用程序关闭后被销毁。

修改 如果您有超过50个链接表,那么在每次启动时刷新它们可能不是一个好主意。相反,您可以根据需要创建包含[local_Appversion,isFreshInstall]和其他一些变量的Local表。每次您的用户收到更新时,freshInstall都将为true,并编写您的应用程序以连接并刷新所有表。 (只是为了确保客户端能够不间断地连接)

所以你的autoExe代码:如果它的freshInstall那么 如果不是只设置connectionString,则连接和刷新链接。 (登录后通常会出现启动画面以执行此操作) 成功连接后,只需将本地isFreshInstall值更新为false,以便下次更快启动。

您还可以拥有一个专用菜单,用户可以手动点击并刷新链接。(如果连接被删除) 就像是 custom menu for access

如果您的组织有域,则可以使用Windows登录名允许可信连接 祝你好运。