System.Security.SecurityException 具有 CLR 功能
System.Security.SecurityException with CLR Function
首先,我会说这个问题与有关。
但是,我会把所有的东西都移到这里以供参考。
我遇到的问题是我仍然收到错误:
Msg 6522, Level 16, State 1, Procedure PerfInsert, Line 0 [Batch Start Line 31]
A .NET Framework error occurred during execution of user-defined routine or aggregate "PerfInsert":
System.Security.SecurityException: Request failed.
System.Security.SecurityException:
at MiddleMan.MiddleMan.CreateCommand(SqlString tblString, SqlString featureName, SqlString connectionString, SqlString perfionConnectionString, SqlString logFile)
.
即使我相信我已经按照正确设置的所有必要步骤进行操作。我什至已经验证 SQL 服务器对文件目录具有权限。
任何人都知道我还能检查什么以查看丢失的部分是什么?
或者我需要将其设为 "unsafe" 程序集吗?
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-1\c$\SQL Server C# Functions\MiddleMan\MiddleMan\bin\Release\MiddleMan.dll'
WITH PERMISSION_SET = SAFE
GO
CREATE ASYMMETRIC KEY [Brock.Retail_Brock.Retail_Brock]
AUTHORIZATION [dbo]
FROM EXECUTABLE FILE = '\bk-int-1\c$\SQL Server C# Functions\MiddleMan\MiddleMan\bin\Release\MiddleMan.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
),您将需要做在将 Assembly 设置为 UNSAFE
之前执行以下操作:
USE [master];
GRANT UNSAFE ASSEMBLY TO [BrokcRetail];
然后:
USE [{db_containing_assembly_hopefully_not_master];
ALTER ASSEMBLY [PerfInsert] WITH PERMISSION_SET = UNSAFE;
或者,如果您创建基于非对称密钥的登录并首先授予它 UNSAFE ASSEMBLY
权限,那么您可以在 [=18] 中简单地使用 UNSAFE
而不是 SAFE
=]声明。
从 SQL Server 2017 开始,您需要在 创建程序集之前创建非对称密钥和关联的登录名 。非对称密钥和登录进入 [master]
而程序集可以进入任何数据库(包括 [master]
,但通常最好不要将自定义代码放在那里)。
如果您已经在使用 SQL Server 2017 或更新版本,并且问题中显示的代码与您执行它的实际顺序一致,那么我猜您已经设置了数据库 TRUSTWORTHY ON
或禁用 [=72=]。否则,如果没有先创建基于签名的登录 并且 授予 UNSAFE ASSEMBLY
权限,您根本无法创建程序集。如果我对此是正确的,您可以为该数据库重新启用 "CLR strict security" and/or 转 TRUSTWORTHY OFF
。
此外,正如我在您的相关问题(与此问题相关的问题)中指出的那样,您应该使用 SqlString
而不是 SqlChars
。 SqlString.Value
returns .NET string
而 SqlChars.Value
returns char[]
。很久以前人们将 SqlChars
与 NVARCHAR(MAX)
相关联,将 SqlString
与 NVARCHAR(1-4000)
相关联,但这只是由于 Visual Studio / SSDT 在生成DDL 发布数据库项目。但是它们之间从来没有任何技术/字符串映射。您可以将任一 .NET 类型与任一 T-SQL 数据类型一起使用。
此外,在 SQLCLR 中使用多线程时请谨慎行事(并进行大量测试)。
请访问 SQLCLR Info 以获取更多与使用 SQLCLR 相关的一般资源。
相关帖子:
- System.Web in SQL Server CLR Function(在 DBA.StackExchange 上)
首先,我会说这个问题与
但是,我会把所有的东西都移到这里以供参考。
我遇到的问题是我仍然收到错误:
Msg 6522, Level 16, State 1, Procedure PerfInsert, Line 0 [Batch Start Line 31] A .NET Framework error occurred during execution of user-defined routine or aggregate "PerfInsert": System.Security.SecurityException: Request failed. System.Security.SecurityException: at MiddleMan.MiddleMan.CreateCommand(SqlString tblString, SqlString featureName, SqlString connectionString, SqlString perfionConnectionString, SqlString logFile) .
即使我相信我已经按照正确设置的所有必要步骤进行操作。我什至已经验证 SQL 服务器对文件目录具有权限。
任何人都知道我还能检查什么以查看丢失的部分是什么?
或者我需要将其设为 "unsafe" 程序集吗?
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-1\c$\SQL Server C# Functions\MiddleMan\MiddleMan\bin\Release\MiddleMan.dll'
WITH PERMISSION_SET = SAFE
GO
CREATE ASYMMETRIC KEY [Brock.Retail_Brock.Retail_Brock]
AUTHORIZATION [dbo]
FROM EXECUTABLE FILE = '\bk-int-1\c$\SQL Server C# Functions\MiddleMan\MiddleMan\bin\Release\MiddleMan.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
),您将需要做在将 Assembly 设置为 UNSAFE
之前执行以下操作:
USE [master];
GRANT UNSAFE ASSEMBLY TO [BrokcRetail];
然后:
USE [{db_containing_assembly_hopefully_not_master];
ALTER ASSEMBLY [PerfInsert] WITH PERMISSION_SET = UNSAFE;
或者,如果您创建基于非对称密钥的登录并首先授予它 UNSAFE ASSEMBLY
权限,那么您可以在 [=18] 中简单地使用 UNSAFE
而不是 SAFE
=]声明。
从 SQL Server 2017 开始,您需要在 创建程序集之前创建非对称密钥和关联的登录名 。非对称密钥和登录进入 [master]
而程序集可以进入任何数据库(包括 [master]
,但通常最好不要将自定义代码放在那里)。
如果您已经在使用 SQL Server 2017 或更新版本,并且问题中显示的代码与您执行它的实际顺序一致,那么我猜您已经设置了数据库 TRUSTWORTHY ON
或禁用 [=72=]。否则,如果没有先创建基于签名的登录 并且 授予 UNSAFE ASSEMBLY
权限,您根本无法创建程序集。如果我对此是正确的,您可以为该数据库重新启用 "CLR strict security" and/or 转 TRUSTWORTHY OFF
。
此外,正如我在您的相关问题(与此问题相关的问题)中指出的那样,您应该使用 SqlString
而不是 SqlChars
。 SqlString.Value
returns .NET string
而 SqlChars.Value
returns char[]
。很久以前人们将 SqlChars
与 NVARCHAR(MAX)
相关联,将 SqlString
与 NVARCHAR(1-4000)
相关联,但这只是由于 Visual Studio / SSDT 在生成DDL 发布数据库项目。但是它们之间从来没有任何技术/字符串映射。您可以将任一 .NET 类型与任一 T-SQL 数据类型一起使用。
此外,在 SQLCLR 中使用多线程时请谨慎行事(并进行大量测试)。
请访问 SQLCLR Info 以获取更多与使用 SQLCLR 相关的一般资源。
相关帖子:
- System.Web in SQL Server CLR Function(在 DBA.StackExchange 上)