MSSQL CLR 拒绝访问路径“c:\some\path”

Wil*_*llG 8 sql-server permissions sql-clr files sql-server-2016

我认为这是一个权限问题,但我无法找到它。

我在一台服务器(SQL Server 2016)上有一组 CLR,它们可以正常工作。所有这些都被标记为 UNSAFE,并且它们执行各种类型的文件 I/O(读取、写入、复制、移动、重命名等)。我可以通过 SSMS 或同样轻松地从工作中运行它们。

我需要将它们安装在另一台服务器(也是 SQL Server 2016)上。使用原始的 Visual Studio 项目,我已将它们部署到新服务器。它们出现在 SSMS 中。那部分看起来不错。

当我从 SSMS 尝试运行一个时,我收到以下错误:“拒绝访问路径‘我传入的任何路径’。”

我在 Windows 登录下登录到 SSMS。我有数据库的权限,我是 dbo。我是服务器管理员。我在文件系统中有权限。

我还能缺少什么?

Sol*_*zky 12

我有数据库的权限,我是 dbo。我是服务器管理员。我在文件系统中有权限。

通常,这些都不重要。除非您(或编写 SQLCLR 方法的人)实现了 Impersonation,否则用于外部操作的安全上下文是运行 SQL Server 的服务帐户的安全上下文(类似于xp_cmdshell行为)。正是该帐户需要您尝试访问的路径的权限。

为了文件访问权限的完整性:

  1. 对于本地(在盒子上)访问,它很简单
    1. 需要权限的数据库引擎(即 MSSQLSERVER 或 MSSQL$InstanceName)服务的服务帐户(默认行为),或
    2. 如果代码中实现了模拟
      1. 并且执行代码的登录名是Windows登录名,而不是SQL Server登录名,那么需要权限的是那个Windows帐户
      2. 但是正在使用 SQL Server 登录名,外部访问仍然作为数据库引擎服务帐户完成
  2. 对于远程访问(共享驱动器),可能需要设置约束委派(通过 Active Directory;包括 SPN)。好的 'ol Kerberos 双跳问题。在这种情况下,您会看到从另一台计算机登录 SQL Server 与直接登录到运行 SQL Server 的服务器然后连接到本地 SQL Server 实例之间的区别。

请记住,“拒绝”优先于“授予”(就像 SQL Server 权限一样)。

为了确定用于外部访问的帐户是否确实对文件夹和/或文件具有必要的权限:

  1. 转到相关路径的“属性”(报告错误的特定文件或文件夹)
  2. 转到“安全”选项卡
  3. 点击“高级”按钮
  4. 转到“有效访问”选项卡
  5. 单击“选择用户”链接
  6. 输入完整的帐户名称(例如NT Service\MSSQLSERVER
  7. 单击“确定”按钮
  8. 点击“查看有效访问”按钮
  9. 该帐户是否有权访问该资源?

您尝试访问的路径中是否有任何拒绝权限?


另外如果所有代码都在做文件系统的事情,那么很可能你不需要将程序集标记为UNSAFE,而应该是EXTERNAL_ACCESS. 不需要太多的文件系统操作UNSAFE。其中之一是获取固定驱动器列表,但不确定还有什么。