c# - 具有 CLR 函数的 System.Security.SecurityException

标签 c# sql-server sqlclr

首先,我会说这个问题与 my previous post 有关。 .

但是,我会将所有内容移到此处以供引用。

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

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 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-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

最佳答案

您正在使用多线程,所以是的,程序集 100% 需要具有 PERMISSION_SET = UNSAFE

此外,由于您已经设置了非对称 key 和关联的登录名(感谢您这样做,并且使用 TRUSTWORTHY ON ),因此您需要在设置程序集之前执行以下操作不安全:

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

然后:

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

或者,如果您创建基于非对称 key 的登录并首先授予其 UNSAFE ASSEMBLY 权限,那么您可以简单地使用 UNSAFE 而不是 SAFECREATE ASSEMBLY 语句中。

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

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

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

此外,在 SQLCLR 中使用多线程时请务必小心(并进行大量测试)。

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

相关帖子:

  1. System.Web in SQL Server CLR Function (在 DBA.StackExchange 上)
  2. CREATE PROCEDURE gets “Msg 6567, Level 16, State 2” for SQLCLR stored procedure

关于c# - 具有 CLR 函数的 System.Security.SecurityException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58646378/

相关文章:

c# - 我应该将哪些参数传递给 ViewModel 的构造函数?

c# - 使用 IQueryable 的单元测试代码

sql-server - 数据库表定义中的列排序是否有标准/约定?

sql-server - SQL Server : Could not find type in the assembly

azure - 每小时对 API 进行 REST 调用并将结果保存到 Azure SQL

c# - 如何在 C# 中对属性进行分组?

c# - 如何将空值插入到 Uniqueidentifier 列

sql-server - 从 S3 存储桶还原 AWS RDS SQL Server 上的备份文件

sql - 摆脱 SQL Server 中的 "Magic"数字

.net - 是否可以反编译 SQL Server CLR 存储过程程序集?