Sql 服务器 2012 的用户定义函数的安全问题

Security issues on user defined functions for Sql server 2012

我正在用 C# 创建用户定义函数,如 link 中所述:https://msdn.microsoft.com/en-us/library/w2kae45k%28v=vs.90%29.aspx

(我使用C# CLR项目,我有VS 2010,SQL服务器2012。VS 2010中的代码在框架3.5中。sql服务器在框架4.0中)

我没有成功部署,即使我选择了正确的服务器+数据库,所以我像这样手动复制dll:

  1. 创建了新的 sql 项目作为 link(我选择了 Visual C# CLR 数据库 object,选择服务器+数据库)
  2. 添加用户自定义函数:

    使用系统; 使用 System.Data; 使用 System.Data.SqlClient; 使用 System.Data.SqlTypes; 使用 Microsoft.SqlServer.Server;

    public 部分 class UserDefinedFunctions { [Microsoft.SqlServer.Server.SqlFunction()] public static int testfunc() { // 把你的代码放在这里 return1234; } };

  3. 将dll放到sql服务器的程序集中(在sqlssms中:databases->"database name" -> Programmability -> Assembly -> New assembly -> ... 选择权限设置为 "safe").

  4. 的 dll
  5. 像这样添加一个新函数: 创建函数 testfunc() RETURNS 整数 作为 外部名称 SqlServerProject1.UserDefinedFunctions.testfunc

(SqlServerProject1 是命名空间和 dll 名称,UserDefinedFunctions 是 class 名称,testfunc 是 C# 和 sql 服务器中的函数名称)

  1. 在执行 select dbo.funcname() 时一切正常,但现在我遇到了问题(请参阅下面的异常),将 C# (testfunc) 中的代码更改为此代码时:

    [Microsoft.SqlServer.Server.SqlFunction()] public static int testfunc() { WebClient webC = new WebClient(); WebRequest req = HttpWebRequest.Create("http://axdev:8090"); return12345; }

    1. 运行ning select dbo.testfunc()时出现异常,得到:

Msg 6522, Level 16, State 2, Line 1 A .NET Framework error occurred during execution of user-defined routine or aggregate "testfunc": System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. System.Security.SecurityException: at System.Security.CodeAccessSecurityEngine.CheckNReturnSO(PermissionToken permToken, CodeAccessPermission demand, StackCrawlMark& stackMark, Int32 create) at System.Security.CodeAccessSecurityEngine.Assert(CodeAccessPermission cap, StackCrawlMark& stackMark) at System.Security.CodeAccessPermission.Assert() at UserDefinedFunctions.testfunc()

  1. 我无法创建具有权限集 = "unrestricted" 的程序集(与步骤 3 相同,但使用 "unrestricted",因为我收到错误:

> 标题:Microsoft SQL Server Management Studio

创建 SqlAssembly 'SqlServerProject1' 失败。 (Microsoft.SqlServer.Smo)

如需帮助,请单击:http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=11.0.3000.0+((SQL11_PCU_Main).121019-1325+)&EvtSrc=Microsoft.SqlServer.Management.Smo.ExceptionTemplates.FailedOperationExceptionText&EvtID=Create+SqlAssembly&LinkId=20476


附加信息:

执行 Transact-SQL 语句或批处理时发生异常。 (Microsoft.SqlServer.ConnectionInfo)


为程序集 'SqlServerProject1' 创建程序集失败,因为程序集 'SqlServerProject1' 未获得 PERMISSION_SET = 不安全的授权。当以下任一情况为真时,程序集被授权:数据库所有者 (DBO) 具有 UNSAFE ASSEMBLY 权限并且数据库具有 TRUSTWORTHY 数据库 属性;或者程序集使用证书或非对称密钥签名,该证书或非对称密钥具有具有 UNSAFE ASSEMBLY 权限的相应登录名。 (Microsoft SQL 服务器,错误: 10327)

如需帮助,请单击:http://go.microsoft.com/fwlink?ProdName=Microsoft%20SQL%20Server&ProdVer=11.00.3128&EvtSrc=MSSQLServer&EvtID=10327&LinkId=20476


按钮:

好的

  1. 如何正确解决上述问题 运行 新的 testfunc 代码?

========

一个新问题 - 在 运行ning alter database 'mydb' set trustworthy on 之后,我得到一个新错误,当再次添加带有 "permission set" = unrestricted 的程序集时。

TITLE: Microsoft SQL Server Management Studio

Create failed for SqlAssembly 'SqlServerProject1'. (Microsoft.SqlServer.Smo)

For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=11.0.3000.0+((SQL11_PCU_Main).121019-1325+)&EvtSrc=Microsoft.SqlServer.Management.Smo.ExceptionTemplates.FailedOperationExceptionText&EvtID=Create+SqlAssembly&LinkId=20476

------------------------------ ADDITIONAL INFORMATION:

An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)


The database owner SID recorded in the master database differs from the database owner SID recorded in database 'mydb'. You should correct this situation by resetting the owner of database 'mydb' using the ALTER AUTHORIZATION statement. (Microsoft SQL Server, Error: 33009)

For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft%20SQL%20Server&ProdVer=11.00.3128&EvtSrc=MSSQLServer&EvtID=33009&LinkId=20476

谢谢:)

将权限更改为无限制访问是一种不好的做法。最好创建一个具有无限制权限的新登录访问权限,并将其用于 clr 调用。您必须在 clr 程序集中使用某些线程或套接字编程。它确实需要不受限制的访问。