首先,请注意,我知道这个问题已经问过好几次了。然而,到目前为止,已被接受的(和未被接受的)解决方案在我的案例中没有起作用,因此,从那时起,一些实质性的问题肯定发生了变化,希望这有理由再次提出要求。
在这样说之后:
我目前正在尝试升级Access 2010 .adp应用程序以访问2019年.accdb。该应用程序包含大量使用ADO对象连接Microsoft并在其上操作的VBA代码(目前为: 2008 R2,但将很快升级)。
我想保留大部分代码,这意味着要坚持使用ADO,所以接下来的方法是新的OleDB SQL server驱动程序(它在2018年被取消推荐/新发布)。SQL服务器在我的客户端应用程序之外的另一台计算机上运行。
我无法从VBA建立到SQL服务器的连接。执行以下代码段时
Dim cnTemp As Connection
Set cnTemp = New Connection
cnTemp.CursorLocation = adUseServer
cntemp.Open "Provider=MSOLEDBSQL;Server=dbserver.example.com;Initial Catalog=MyDB;Authentication=SqlPassword;User ID=sa;Password=secret;DataTypeCompatibility=80;"
执行最后一行时,我会得到以下错误:
SSL Provider: The certificate chain was issued by an authority which is not trusted.
好的,没问题,毕竟我们已经找到了处理相同问题的所有其他问题,都提出了相同的解决方案:将Trust Server Certificate=True;
添加到连接字符串中。
嗯,试过了,但-to我的惊喜-仍然是相同的情况。然后,我尝试了其他一些变体,如TrustServerCertificate=True;
或使用true
而不是True
,但都没有效果。我还尝试添加Use Encryption for Data=True;
,但这也没有帮助(这是可以预料到的)。此外,我尝试了我在研究这个问题时发现的一些片段,但微软并没有记录这些片段在ADO连接字符串(如Encrypt=true
或Trusted_Connection=true;
)中是有效的;当然,这会使情况变得更糟,引发其他错误消息。
我已经了解到,我可以通过将SQL服务器证书放入客户端的可信根证书存储区,或者让SQL server使用已知的、可信的CA颁发的证书(例如,让我们加密)来解决这个问题。
但是,我非常想知道为什么在连接字符串中添加Trust Server Certificate=true;
不会使错误消失,我需要在其中添加什么来禁用证书验证(顺便说一句,如果我们不开始讨论为什么这会不好;这只是在可信的封闭网络中进行开发和测试,我知道可能存在的风险)。
发布于 2019-09-28 22:26:17
连接字符串中的TrustServerCertificate=True
未被执行的原因有两个。一是它不是一个有效的ADO经典(ADODB)连接字符串关键字。根据ActiveX数据对象连接字符串关键字文档,关键字/值对应该是Trust Server Certificate=True
(注释空格)。关键字被完全忽略,没有空格,因此不受信任。
但是,由于Authentication-SqlPassword
规范的原因,仅此更改将不信任证书。当指定Authentication
关键字时,文档脚注将调用:
为了提高安全性,在使用身份验证/访问令牌初始化属性或其相应的连接字符串关键字时,将修改加密和证书验证行为。有关详细信息,请参阅加密和证书验证链接。
引用的链接包括以下重要说明:
还可以通过HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\SNI18.0\GeneralFlags\Flag2注册表项的Value字段来控制证书验证。有效值为0或1。OLE DB驱动程序在注册表和连接属性/关键字设置之间选择最安全的选项。也就是说,只要至少有一个注册表/连接设置启用服务器证书验证,驱动程序就会验证服务器证书。
因此,即使使用Trust Server Certificate=True
,当此注册表值设置为0时,也将验证cert。
一种解决方案是简单地删除Authentication=SqlPassword
规范,只要您不需要通过不信任服务器证书所提供的改进的安全性:
cntemp.Open "Provider=MSOLEDBSQL;Server=dbserver.example.com;Initial Catalog=MyDB;User ID=sa;Password=secret;Trust Server Certificate=True;DataTypeCompatibility=80;"
发布于 2019-09-29 07:23:30
首先,我想说,所有的功劳都归于@。正是他的回答/评论提供了解决办法。
然而,我想补充一些背景,基于我在发布我的问题后所做的研究。
问题是微软的文档显然是错误的。请看下列文件:
它位于SQL Server 2017 -> OLE DB -> Applications -> Using connection string keywords with OLE DB Driver for SQL server
部分,所以应该是正确的。它分为三个部分;在这个问题的上下文中,最后一个表是我们感兴趣的内容,因为只有这个表涉及到与ADO的连接字符串。
最后一个表显式地显示了Authentication=SqlPawword
在ADO / OLE DB连接字符串中是有效的(重新格式化我的,没有修改内容):
身份验证SSPROP_AUTH_MODE指定使用的SQL或Active身份验证。有效值是:
(not set)
:由其他关键字确定的身份验证模式。ActiveDirectoryPassword
:使用登录ID和密码的Active身份验证。ActiveDirectoryIntegrated
:使用当前登录用户的Windows帐户凭据对Active的集成身份验证。 注意:建议使用集成安全性(或Trusted_Connection)身份验证关键字或其相应属性的应用程序将身份验证关键字(或其相应属性)的值设置为ActiveDirectoryIntegrated,以启用新的加密和证书验证行为。SqlPassword
:使用登录ID和密码进行身份验证。 注意:建议使用Server身份验证的应用程序将身份验证关键字(或其相应的属性)的值设置为SqlPassword,以启用新的加密和证书验证行为。
它还说(同样,格式化我的,没有修改内容):
信任服务器证书SSPROP_INIT_TRUST_SERVER_CERTIFICATE接受字符串"true“和"false”作为值。默认值为"false",这意味着将验证服务器证书。
每个通情达理的人都会理解这一点,因为Trust Server Certificate=true
将禁用证书验证。
但当你看着这里
您将注意到,这个文档的结构与第一个文档类似,最后一个表没有提到Authentication
参数。
但是,此文档位于SQL Server 2017 -> Development -> SQL Server Native Client -> Applications -> Using Connection String Keywords
中。这意味着它与我们的情况无关,因为它与SQL server本机客户机(而不是OLE DB)有关,但它提供了正确的信息。
因此,我们有提供错误信息的正确文档和提供正确信息的不相关文档。恭喜你,微软,你又让我浪费了一整天.
此外,我发现以下文件:
阅读标题(“使用Azure Active Directory"),它应该只与Azure相关。但是,我怀疑以下部分也涉及本地SQL server安装(格式化我的,没有修改内容):
证书验证 为了提高安全性,新的连接属性/关键字独立于客户端加密设置来尊重TrustServerCertificate设置(及其相应的连接字符串关键字/属性)。因此,服务器证书在默认情况下是有效的。 备注 还可以通过HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\SNI18.0\GeneralFlags\Flag2注册表项的Value字段来控制证书验证。有效值为0或1。OLE DB驱动程序在注册表和连接属性/关键字设置之间选择最安全的选项。也就是说,只要至少有一个注册表/连接设置启用服务器证书验证,驱动程序就会验证服务器证书。
因此,在通过ADO / OLE DB连接到SQL服务器时,我们很可能还必须更改注册表中的值,以最终禁用证书验证。
https://stackoverflow.com/questions/58150324
复制相似问题