Access前端对接Azure SQL:实现ADO与ODBC的Azure AD单次会话认证
我用MS Access作为Azure SQL Server后端的前端,分别通过ADO和ODBC连接字符串实现不同功能(执行后端任务、链接前端表)。当前采用Azure Active Directory Interactive身份验证,每次会话首次使用两种连接字符串时,都会弹出输入Microsoft密码的提示,用户需要重复输入两次(一次针对ADO,一次针对ODBC)。
已实现正常连接,但现有Stack Overflow相关内容未解决单次验证的需求,希望用户每次会话仅完成一次身份验证。
当前的连接字符串生成函数如下(两种类型均可正常工作):
Select Case connectionType Case "ADO": ConnectionString = "Provider=MSOLEDBSQL19;&" & _ "Data Source=" & serverName & ";" & _ "Initial Catalog=" & databaseName & ";" & _ "Authentication=ActiveDirectoryInteractive;&" & _ "User ID=" & userEmail & ";" & _ "Use Encryption for Data=true;" Case "ODBC": ConnectionString = "ODBC;&" & _ "DRIVER=ODBC Driver 17 for SQL Server;&" & _ "SERVER=" & serverName & ";" & _ "DATABASE=" & databaseName & ";" & _ "UID=" & userEmail & ";" & _ "Authentication=ActiveDirectoryInteractive;&" & _ "Encrypt=yes;" End Select
此前尝试将ODBC连接的Authentication改为ActiveDirectoryIntegrated但未生效,且公司安全限制无法使用Windows凭据、不能硬编码用户名和密码。
以下是可行的解决方案:
统一驱动版本,共享身份缓存
不同版本的SQL Server驱动会维护独立的身份验证缓存,统一ADO和ODBC的驱动版本即可共享会话。将ODBC驱动升级到ODBC Driver 18 for SQL Server,与ADO使用的MSOLEDBSQL19版本匹配,修改后的ODBC连接字符串:ConnectionString = "ODBC;&" & _ "DRIVER=ODBC Driver 18 for SQL Server;&" & _ "SERVER=" & serverName & ";" & _ "DATABASE=" & databaseName & ";" & _ "UID=" & userEmail & ";" & _ "Authentication=ActiveDirectoryInteractive;&" & _ "Encrypt=yes;&" & _ "TrustServerCertificate=no;"通过ADO获取访问令牌,复用至ODBC连接
先初始化ADO连接完成身份验证,获取访问令牌后将其嵌入ODBC连接字符串,避免二次验证:- 通过ADO连接获取访问令牌:
Dim adoConn As Object Set adoConn = CreateObject("ADODB.Connection") adoConn.Open ConnectionString("ADO") Dim token As String token = adoConn.Properties("Access Token").Value - 修改ODBC连接字符串,使用令牌验证:
ConnectionString = "ODBC;&" & _ "DRIVER=ODBC Driver 18 for SQL Server;&" & _ "SERVER=" & serverName & ";" & _ "DATABASE=" & databaseName & ";" & _ "AccessToken=" & token & ";" & _ "Encrypt=yes;"
注意:需确保ODBC驱动版本在17及以上,ADO连接的Provider为MSOLEDBSQL19才能支持
Access Token属性。- 通过ADO连接获取访问令牌:
使用统一DSN配置共享会话
创建用户/系统DSN,配置为Azure AD Interactive身份验证(驱动用ODBC Driver 18),然后在ADO和ODBC连接中均引用该DSN:- ADO连接字符串修改为:
ConnectionString = "Provider=MSOLEDBSQL19;&" & _ "Data Source=" & serverName & ";" & _ "Initial Catalog=" & databaseName & ";" & _ "Authentication=ActiveDirectoryInteractive;&" & _ "User ID=" & userEmail & ";" & _ "Use Encryption for Data=true;&" & _ "DSN=YourAzureSQLDSN;" - ODBC连接直接使用DSN:
ConnectionString = "ODBC;DSN=YourAzureSQLDSN;"
统一DSN后,驱动会复用同一个身份验证会话,避免重复弹窗。
- ADO连接字符串修改为:
内容的提问来源于stack exchange,提问作者kdickinson

