38

当我尝试从 .Net 程序集(.Net 3.5)在 SQL 2008 中创建程序集时,出现以下错误,错误提示我必须将以下任一属性设置为 true,我该怎么做?

数据库所有者 (DBO) 的 EXTERNAL ACCESS ASSEMBLY 权限为 TRUE

数据库具有 TRUSTWORTHY 数据库属性

该程序集使用证书或非对称密钥进行签名,该密钥具有相应的登录名并具有外部访问程序集权限。

完整的错误如下,

为程序集“SQLLogger”创建程序集失败,因为程序集“SQLLogger”未获得 PERMISSION_SET = EXTERNAL_ACCESS 的授权。当以下任一情况为真时,程序集被授权:数据库所有者 (DBO) 具有 EXTERNAL ACCESS ASSEMBLY 权限并且数据库具有 TRUSTWORTHY 数据库属性;或者程序集使用证书或非对称密钥签名,该证书或非对称密钥具有相应的登录并具有外部访问程序集权限。

提前致谢!

4

7 回答 7

44

This worked for me:

EXEC sp_changedbowner 'sa'
ALTER DATABASE [dbase] SET trustworthy ON

and I also did this:

sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO

sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO

sp_configure 'show advanced options', 0;
GO
RECONFIGURE;
GO
于 2014-06-30T10:37:36.377 回答
33

⚠‼请不要设置... TRUSTWORTHY ON

...除非绝对必要‼ 而且,它几乎永远不会是“必要的”,即使在加载您未构建的程序集时(您总是可以添加另一个证书,或者最坏的情况:加载到 SQL Server签名),或者在加载不受“支持”并因此不在 SQL Server 的 CLR 主机中的 .NET Framework 库时(您可以使用它们签名的证书,或者最坏的情况:加载到 SQL Server后签名)。将数据库设置为TRUSTWORTHY ON打开一个安全漏洞,有关此的更多信息,请参阅:

请,请,请停止使用模拟、可信和跨数据库所有权链接

反而,

最好执行以下操作:

USE [master];

CREATE ASYMMETRIC KEY [SomeKey]
  AUTHORIZATION [dbo]
  FROM EXECUTABLE FILE = 'C:\path\to\Some.dll';

CREATE LOGIN [SomeLogin]
  FROM ASYMMETRIC KEY [SomeKey];

GRANT EXTERNAL ACCESS ASSEMBLY TO [SomeLogin]; -- or "UNSAFE" instead of "EXTERNAL ACCESS"

每个实例,每个键只需要执行上述操作一次。因此,如果您对所有程序集使用相同的snk/pfx文件,那么上面显示的步骤只需为每个 SQL Server 实例执行一次;包含这些程序集的程序集和数据库的数量无关紧要。或者,如果使用证书签名,则只需在上面显示的示例代码中替换ASYMMETRIC KEY为。CERTIFICATE

这种方法允许您在数据库上保持更好的安全性(通过保持TRUSTWORTHY设置为OFF)并允许更精细地控制甚至允许将哪些程序集设置为EXTERNAL_ACCESS和/或UNSAFE(因为您可以通过使用不同的密钥进行签名和基于登录的在那些不同的键上)。

但是,如果必须使用该TRUSTWORTHY ON方法,则数据库所有者不必是sa. 要求仅仅是注册为数据库所有者的登录已被授予EXTERNAL ACCESS ASSEMBLYUNSAFE ASSEMBLY(与上面显示的基于非对称密钥的登录相同的两个权限)。意义:

USE [master];
GRANT UNSAFE ASSEMBLY TO [{Login-that-is-dbo-for-DB-containing-Assembly}];

有关安全选项的更详细演练,请参阅我在 SQL Server Central 上撰写的以下文章:SQLCLR 级别 4 的阶梯:安全性(外部和不安全的程序集)


有关如何通过 Visual Studio / SSDT 自动执行此操作的详细演练,请参阅 SQL Server Central 上的以下 3 篇文章(由 3 部分组成的系列):

另外,自从写了这 3 篇文章后,我想出了一个使用 T4 模板的更简单的方法,但还没有时间写出来。当我这样做时,我将使用该文章的链接更新此答案。

更新

SQL Server 2017 以名为“CLR strict security”的服务器级配置选项的形式引入了一个新的复杂功能。它默认启用,并要求所有程序集,即使是标记为 的程序SAFE集,都使用证书或非对称密钥进行签名,具有关联的登录名,并且登录名具有授予的UNSAFE ASSEMBLY权限(不足以授予EXTERNAL ACCESS ASSEMBLY)。有关此新“功能”的更多详细信息,请参阅我对以下 SO 问题的回答:

SQL Server 2017 上的 CLR 严格安全性

于 2015-08-23T18:16:49.350 回答
15

您必须在项目文件中设置这些设置!当您右键单击您的项目时,单击项目配置中的数据库设置并选择其他选项卡。你应该看到类似于我在这里的东西:项目设置

这与以下问题相同:Error Running CLR Stored Proc

于 2013-03-26T18:10:28.580 回答
6

以下代码适用于我的集成安全性:

ALTER DATABASE dtabasename SET TRUSTWORTHY ON;
GO

ALTER AUTHORIZATION ON DATABASE::dtabasename TO [DOMAIN\UserName]
GO
于 2014-10-20T12:38:16.527 回答
5

这适用于:

  • Visual Studio 2015 更新 2。
  • 视觉工作室 2017。
  • Visual Studio 2017 和 SQL Server 2019(感谢@Ramkumar Sambandam)。

在您的项目设置中,选择“外部访问”:

在此处输入图像描述

在发布时,错误消息说它不能接受“EXTERNAL_ACCESS”,除非程序集设置为“Trustworthy”。

因此,在项目设置中,将程序集设置为“可信赖”:

在此处输入图像描述

这意味着我能够运行列出本地硬盘驱动器上文件的示例用户定义函数

如果安全性仍然过于严格,请将属性添加DataAccess = DataAccessKind.Read到您的 UDF,例如:

[Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "FindFiles", DataAccess = DataAccessKind.Read, TableDefinition = "FileName nvarchar(500), FileSize bigint, CreationTime datetime")]

2017-07-02 更新

SQL Server 2016+Visual Studio 2015上,您可能还必须执行以下操作:

  • use master;grant unsafe assembly to [Domain\Username];
  • 在模式下运行任何程序(例如 Visual Studio 或任何 C# 实用程序),Administrator以授予它们足够的权限来发布UNSAFE程序集。

如果不起作用,请尝试使用用户名sa和管理员密码进行连接。这将始终有效,无论 Visual Studio 是否在Administrator模式下运行。

2020-01-17 更新

更新了兼容的 VS + SQL Server 组合列表。

于 2016-04-02T21:36:53.383 回答
3

这就是我设法使它工作的方法:

ALTER DATABASE databasename SET trustworthy ON

sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO

sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO

sp_configure 'show advanced options', 0;
GO
RECONFIGURE;
GO

/
DROP ASSEMBLY assemblyname

GO


CREATE ASSEMBLY assemblyname
FROM 0x4D5A9000.....
WITH PERMISSION_SET = EXTERNAL_ACCESS
于 2014-09-30T11:05:11.727 回答
2

this single line solves the problem for me

use master;
grant external access assembly to [domain\username]
于 2013-10-03T08:08:10.553 回答