System.Security.SecurityException with CLR Function

佐手、 提交于 2019-12-12 18:29:24

问题


First off, Ill say that this issue is related to my previous post.

However, I'll move everything over here for reference.

The issue I am having is I am still getting the error:

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

Even though I believe I have followed all the steps necessary to set this up correctly. I have even gone so far as to verify that SQL Server has permissions to the directory of the files.

Anyone know what else I can check to see what the missing piece is?

Or do I need to make this an "unsafe" assembly?

C# code:

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 code(s):

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

回答1:


You are using multi-threading so yes, the Assembly 100% needs to have PERMISSION_SET = UNSAFE.

Also, since you already have the Asymmetric Key and associated Login set up (thank you for doing that and not using TRUSTWORTHY ON), you will need to do the following prior to setting the Assembly to UNSAFE:

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

and then:

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

or, if you create the Asymmetric Key-based Login and grant it the UNSAFE ASSEMBLY permission first, then you can simply use UNSAFE instead of SAFE in the CREATE ASSEMBLY statement.

Starting in SQL Server 2017, you will need to create the Asymmetric Key and associated Login before creating the Assembly. The Asymmetric Key and Login go into [master] while the Assembly can go into any DB (including [master], but usually best to not put custom code in there).

If you are already using SQL Server 2017 or newer, and if the code shown in the question is in the actual order in which you are executing it, then I would guess that you have already either set the database to TRUSTWORTHY ON or disabled "CLR strict security". Otherwise you should not have been able to create the Assembly at all without first having the signature-based login created and granted the UNSAFE ASSEMBLY permission. If I am correct about this, you can re-enable "CLR strict security" and/or turn TRUSTWORTHY OFF for that database.

Also, as I noted on your related question (the one linked to in this question), you should be using SqlString instead of SqlChars. SqlString.Value returns a .NET string while SqlChars.Value returns a char[]. Long ago people associated SqlChars with NVARCHAR(MAX), and SqlString with NVARCHAR(1-4000), but that was only due to Visual Studio / SSDT using those mappings as defaults when generating the DDL to publish the Database Project. But there never was any technical / string mapping between them. You can use either .NET type with either T-SQL datatype.

Also, please exercise caution (and lots of testing) when using multi-threading from within SQLCLR.

Please visit SQLCLR Info for more resources related to working with SQLCLR in general.

Related Posts:

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


来源:https://stackoverflow.com/questions/58646378/system-security-securityexception-with-clr-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!