带有CLR函数的System.Security.SecurityException



首先,我想说这个问题与我之前的帖子有关。

不过,我会把所有东西都移到这里以供参考。

我遇到的问题是我仍然收到错误:

消息6522,级别16,状态1,过程PerfInsert,第0行[批处理开始第31行]在执行用户定义例程或聚合"PerfInsert"期间发生.NET Framework错误:System.Security.SecurityException:请求失败。System.Security.SecurityException:在MiddleMan.MiddleMan.CreateCommand(SqlString tblString,SqlString featureName,SqlString connectionString,SqlString perfionConnectionString,SqlStringlogFile(.

尽管我相信我已经完成了正确设置所需的所有步骤。我甚至验证了SQL Server是否有权访问这些文件的目录。

有人知道我还能查到什么吗?

还是我需要将此程序集设置为"不安全"程序集?

C#代码:

using Microsoft.SqlServer.Server;
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Diagnostics;
namespace MiddleMan
{
public static class MiddleMan
{
[SqlProcedure(Name = "PerfInsert")]
public static SqlInt32 CreateCommand(SqlString tblString, SqlString featureName, SqlString connectionString, SqlString perfionConnectionString, SqlString logFile)
{
Process compiler = new Process();
compiler.StartInfo.FileName = "C:\SQL Server C# Functions\PerfionLoader\PerfionLoader\bin\Release\PerfionLoader.exe";
compiler.StartInfo.Arguments = tblString.Value + " " + featureName.Value + " " + connectionString.Value + " " + perfionConnectionString.Value + " " + logFile.Value;
//compiler.StartInfo.UseShellExecute = false;
//compiler.StartInfo.RedirectStandardOutput = true;
compiler.Start();
return SqlInt32.Zero;
}
}
}

SQL代码:

CREATE ASSEMBLY PerfInsert
AUTHORIZATION dbo
FROM '\bk-int-1c$SQL Server C# FunctionsMiddleManMiddleManbinReleaseMiddleMan.dll'
WITH PERMISSION_SET = SAFE
GO

CREATE ASYMMETRIC KEY [Brock.Retail_Brock.Retail_Brock]
AUTHORIZATION [dbo]
FROM EXECUTABLE FILE = '\bk-int-1c$SQL Server C# FunctionsMiddleManMiddleManbinReleaseMiddleMan.dll';
CREATE LOGIN BrokcRetail
FROM ASYMMETRIC KEY [Brock.Retail_Brock.Retail_Brock]

CREATE PROCEDURE PerfInsert
(
@tblString nvarchar(max)
, @featureName nvarchar(max)
, @connectionString nvarchar(max)
, @perfionConnectionString nvarchar(max)
, @logFiel nvarchar(max)
)
AS EXTERNAL NAME PerfInsert.[MiddleMan.MiddleMan].[CreateCommand]
GO

您正在使用多线程,因此是的,Assembly 100%需要有PERMISSION_SET = UNSAFE

此外,由于您已经设置了不对称密钥和相关登录(感谢您这样做,并且而不是使用TRUSTWORTHY ON(,因此在将程序集设置为UNSAFE之前,您需要执行以下操作:

USE [master];
GRANT UNSAFE ASSEMBLY TO [BrokcRetail];

然后:

USE [{db_containing_assembly_hopefully_not_master];
ALTER ASSEMBLY [PerfInsert] WITH PERMISSION_SET = UNSAFE;

或者,如果创建基于非对称密钥的登录并首先授予其UNSAFE ASSEMBLY权限,则可以在CREATE ASSEMBLY语句中简单地使用UNSAFE而不是SAFE

从SQL Server 2017开始,在创建程序集之前,您需要创建非对称密钥和关联的登录名。不对称密钥和登录名进入[master],而程序集可以进入任何DB(包括[master],但通常最好不要在其中放入自定义代码(。

如果您已经在使用SQL Server 2017或更新版本,并且问题中显示的代码按照您执行它的实际顺序,那么我猜您已经将数据库设置为TRUSTWORTHY ON或禁用了"CLR严格安全"。否则,如果没有首先创建基于签名的登录名并授予UNSAFE ASSEMBLY权限,您就根本无法创建程序集。如果我对此是正确的,您可以重新启用"CLR严格安全性"和/或为该数据库启用TRUSTWORTHY OFF

此外,正如我在您的相关问题(本问题中链接到的问题(中所指出的,您应该使用SqlString而不是SqlCharsSqlString.Value返回.NETstring,而SqlChars.Value返回char[]。很久以前,人们将SqlCharsNVARCHAR(MAX)相关联,将SqlStringNVARCHAR(1-4000)相关联,但这只是由于Visual Studio/SSDT在生成DDL以发布数据库项目时使用这些映射作为默认值。但它们之间从来没有任何技术/字符串映射。可以将任一.NET类型与任一T-SQL数据类型一起使用。

此外,在SQLCLR中使用多线程时,请谨慎(并进行大量测试(。

请访问SQLCLR信息以获取与一般使用SQLCLR相关的更多资源。

相关文章:

  1. SQL Server CLR函数中的System.Web(在DBA.StackExchange上(
  2. CREATE PROCEDURE为SQLCLR存储过程获取"Msg 6567,Level 16,State 2">

最新更新