VBA-从OLEDB连接字符串中删除密码

时间:2018-10-31 22:37:17

标签: excel vba excel-vba connection oledb

我有一个Excel文件,其中包含由多个数据透视表利用的一系列OLEDB连接。我想创建一个VBA函数,以在关闭文件时从该几个连接字符串中删除所有密码(这样用户的密码将不会保留)。首先,我以为我需要做的就是将“保存密码”属性设置为false,如下所示:

Public Sub RemovePasswordByNamePrefix()
    Dim cn As Object
    Dim oledbCn As OLEDBConnection

    For Each cn In ThisWorkbook.connections
        Set oledbCn = cn.OLEDBConnection
        oledbCn.SavePassword = False          
    Next
End Sub

应该可以正常工作,在关闭文件并重新打开文件时,您应该不再在连接字符串中看到密码。不应“保存”:

enter image description here

错误,密码仍然存在...已被“保存”。不知道该功能应该做什么。也许那里指的是不同的密码?因此,我尝试了big hammer approach,不幸的是它有它自己的挑战,到目前为止,我还没有解决这个问题。

我不太确定该怎么做...为什么这么不安全?对于包含此类连接字符串的每个文件,它都会保留纯文本密码,任何访问该文件的人都可以轻松读取。

也许我可以进行某种正则表达式以仅从文件中删除密码?当我在界面中执行此操作时,我的多维数据集将刷新并提示我输入凭据,(我想知道)如果在VBA中执行了该操作,即使触发器在关闭时效果很好,也会发生这种情况吗?

底线:什么是防止这些密码在关闭后保留在文件中的最佳方法?

4 个答案:

答案 0 :(得分:5)

@TomJohnRiddle指出,我应该考虑像following question.一样修改连接字符串。最初,我担心采用这种方法可能会在修改连接字符串后提示用户登录屏幕。但是,由于我没有更好的主意,因此我尝试了一下,而且似乎可行,这是我在模仿的内容:

Public Sub RemovePasswordByNamePrefix()
    Dim cn As Object
    Dim oledbCn As OLEDBConnection

    Dim regEx As New RegExp
    regEx.Pattern = "Password=[^;]*;"

    For Each cn In ThisWorkbook.connections            
        Set oledbCn = cn.OLEDBConnection
        oledbCn.SavePassword = False

        oledbCn.connection = regEx.Replace(oledbCn.connection, "")
        oledbCn.CommandText = "" 'My app repopulates this after open
    Next
End Sub

似乎可行:

enter image description here

因此,我认为我会采用这种方法,但是我仍然愿意接受其他建议。清除所有内容并完全重新加载会很不错,但到目前为止还没有appear to be possible.

我还关心哪些版本的VBA支持"Regex" references。我想要与Excel 2010+ 32/64位兼容的东西。我尚未在任何较旧的版本上对此进行测试(我当前正在运行Office 365)。我认为一切正常,但是过去我一直unpleasantly surprised经历过这些事情。

答案 1 :(得分:2)

有关SQL Server身份验证Authentication in SQL Server的信息,请参见。在那里,您可以使用100%Windows身份验证,也可以使用混合模式(Windows身份验证和密码)。如果您确实想从连接字符串中清除密码,请不要使用混合模式身份验证进行安装,只需运行100%Windows身份验证即可。但是,可能已经部署了一些使用密码编写的代码,因此可能并不总是实用的。

因此,禁止输入密码的另一种方法是使用

Integrated Security=true; 

在您的连接字符串中。关于这个主题的Stack Overflow question受到了广泛欢迎。

答案 2 :(得分:0)

@NigelHeffernan建议使用一种稍有不同的方法,这是一个没有正则表达式的版本:

event_generate

我不确定这种方法的好处(除了缺少另一个库引用),而且我还没有在一个连接字符串/一台机器之外进行测试。我的连接字符串不包含“扩展属性”字段,也许这种方法不适用于这种情况。

答案 3 :(得分:0)

您似乎正在使用DSN,如果您在GUI中使用默认的连接管理工具,则Excel会创建DSN。使用DSN时,即使您未选择“保存密码”,ODBC驱动程序有时也会将明文密码输入到注册表中。

与其允许Excel管理您的连接,还需要您自己对其进行管理。这是MS MVP Ben Clothier的一些示例代码。您将必须修改连接字符串以匹配您的用例。您可能可以在删除现有连接之前复制其详细信息。

Public Function InitConnect(UserName As String, Password As String) As Boolean
‘ Description:  Should be called in the application’s startup
‘               to ensure that Access has a cached connection
‘               for all other ODBC objects’ use.
On Error GoTo ErrHandler

    Dim dbCurrent As DAO.Database
    Dim qdf As DAO.QueryDef
    Dim rst As DAO.Recordset

    ‘<configuration specific to MySQL ODBC driver>

    strConnection = “ODBC;DRIVER={MySQL ODBC 5.1 Driver};” & _
                     “Server=” & ServerAddress & “;” & _
                     “Port=” & PortNum & “;” & _
                     “Option=” & Opt & “;” & _  ‘MySql-specific configuration
                     “Stmt=;” & _
                     “Database=” & DbName & “;”

    Set dbCurrent = DBEngine(0)(0)
    Set qdf = dbCurrent.CreateQueryDef(“”)

    With qdf
        .Connect = strConnection & _
                     “Uid=” & UserName & “;” & _
                     “Pwd=” & Password
        .SQL = “SELECT CURRENT_USER();”
        Set rst = .OpenRecordset(dbOpenSnapshot, dbSQLPassThrough)
    End With
    InitConnect = True

ExitProcedure:
    On Error Resume Next
        Set rst = Nothing
        Set qdf = Nothing
        Set dbCurrent = Nothing
    Exit Function
ErrHandler:
    InitConnect = False
    MsgBox Err.Description & ” (” & Err.Number & “) encountered”, _
        vbOKOnly + vbCritical, “InitConnect”
    Resume ExitProcedure
    Resume
End Function

注意: 这是为MS Access而不是Excel编写的。概念都是一样的。您可能想尝试在Access中创建前端,然后将视图从Access导出到Excel。这样可以更好地控制到后端的链接,并允许您在Access中使用SQL来定义要导出到Excel的内容。

阅读此内容https://www.microsoft.com/en-us/microsoft-365/blog/2011/04/08/power-tip-improve-the-security-of-database-connections/