c# – 加密由SqlDependency创建的存储过程

前端之家收集整理的这篇文章主要介绍了c# – 加密由SqlDependency创建的存储过程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我创建了一个 SqlDependency,以便在特定查询的结果发生变化时触发事件.
// Create a command
sqlConnection conn = new sqlConnection(connectionString);
string query = "SELECT MyColumn FROM MyTable;";
sqlCommand cmd = new sqlCommand(query,conn)
cmd.CommandType = CommandType.Text;

// Register a dependency
sqlDependency dependency = new sqlDependency(cmd);
dependency.OnChange += DependencyOnChange;

执行此代码时,将自动创建一个名为的存储过程

sqlQueryNotificationStoredProcedure-82ae1b92-21c5-46ae-a2a1-511c4f849f76

此程序未加密,违反了我的要求.我有两个选择:

>说服客户,自动生成的程序未加密并不重要,因为它只进行清理工作并且不包含任何真实信息(感谢ScottChamberlain指出这一点).
>找到一种方法来加密sqlDependency生成的存储过程.

我怎样才能完成选项2?

有问题的存储过程的内容

CREATE PROCEDURE [dbo].[sqlQueryNotificationStoredProcedure-b124707b-23fc-4002-aac3-4d52a71c5d6b]
AS
BEGIN
    BEGIN TRANSACTION;

    RECEIVE TOP (0) conversation_handle
    FROM [sqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b];

    IF (
        SELECT COUNT(*)
        FROM [sqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b]
        WHERE message_type_name = 'http://schemas.microsoft.com/sql/ServiceBroker/DialogTimer'
    ) > 0
    BEGIN
        IF (
            ( 
                SELECT COUNT(*)
                FROM sys.services
                WHERE NAME = 'sqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b'
            ) > 0
        )
        DROP SERVICE [sqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b];

        IF (OBJECT_ID('sqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b','SQ') IS NOT NULL)
            DROP QUEUE [sqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b];

        DROP PROCEDURE [sqlQueryNotificationStoredProcedure-b124707b-23fc-4002-aac3-4d52a71c5d6b];
    END

    COMMIT TRANSACTION;
END
GO

解决方法

创建一个DDL触发器,检查是否正在创建名为“sqlQueryNotificationStoredProcedure-”的过程,如果是,请立即使用ENCRYPTION更改它:
CREATE TRIGGER [TR_EncryptQueryNotificationProcedures] 
ON DATABASE
AFTER CREATE_PROCEDURE,ALTER_PROCEDURE
AS
BEGIN
    SET ARITHABORT ON;
    SET NOCOUNT ON;
    IF TRIGGER_NESTLEVEL() > 1 RETURN;

    -- For debugging purposes only
    PRINT CONVERT(NVARCHAR(MAX),EVENTDATA());

    DECLARE @DatabaseName NVARCHAR(128);
    SET @DatabaseName = EVENTDATA().value(
        '(/EVENT_INSTANCE/DatabaseName)[1]','NVARCHAR(128)'
    );
    DECLARE @Schema NVARCHAR(128);
    SET @Schema = EVENTDATA().value(
        '(/EVENT_INSTANCE/SchemaName)[1]','NVARCHAR(128)'
    );
    DECLARE @Name NVARCHAR(128);
    SET @Name = EVENTDATA().value(
        '(/EVENT_INSTANCE/ObjectName)[1]','NVARCHAR(128)'
    );

    DECLARE @Definition NVARCHAR(MAX);
    SELECT @Definition = 
        OBJECT_DEFINITION(
            OBJECT_ID(
                QUOTENAME(@DatabaseName) + '.' + 
                QUOTENAME(@Schema) + '.' + 
                QUOTENAME(@Name),'P'
            )
        )
    ;

    -- If the sproc is already encrypted,we can't do anything with it
    IF @Definition IS NULL RETURN;  

    SELECT @Definition = STUFF(
        @Definition,CHARINDEX('CREATE',@Definition),LEN('CREATE'),'ALTER'
    );

    IF 
        @Name LIKE 'sqlQueryNotificationStoredProcedure-%' AND
        -- this should always be false since we can't read encrypted definitions,-- but just to make sure 
        @Definition NOT LIKE '%WITH ENCRYPTION AS BEGIN%' 
    BEGIN;
        SET @Definition = REPLACE(
            @Definition,'AS' + CHAR(13) + CHAR(10) + 'BEGIN','WITH ENCRYPTION AS BEGIN'
        );
        EXEC (@Definition);
    END;
END;
GO
ENABLE TRIGGER [TR_EncryptQueryNotificationProcedures] ON DATABASE;

免责声明:未针对实际依赖性通知进行测试,但基本思路是合理的.它非常脆弱,因为它取决于程序的确切形式,当然 – 使其更加健壮是可能的,但是单调乏味.

猜你在找的C#相关文章