2014-12-03 16 views
7

Utworzono , aby zdarzenie mogło zostać wywołane, gdy zmieni się wynik danego zapytania.Zaszyfruj procedurę składowaną utworzoną przez 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; 

Po wykonaniu tego kodu, procedura przechowywana jest automatycznie tworzony z nazwą jak

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

Ta procedura jest szyfrowane co narusza podane mi wymagania. Mam dwie opcje:

  1. przekonać klienta, że ​​to nie ma znaczenia, że ​​procedura auto generowany jest szyfrowanych, ponieważ jedynie wykonuje prace porządkowe i nie zawiera prawdziwe informacje (dzięki ScottChamberlain za wskazanie na to uwagę).
  2. Znajdź sposób szyfrowania procedury składowanej generowanej przez SqlDependency.

Jak mogę wykonać opcję 2?


Zawartość procedury przechowywane w pytaniu:

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

Co to jest procedura, która wymaga szyfrowania? Nie mam przed sobą środowiska programistycznego, ale myślę, że cały ten proces dotyczy oczyszczenia w przypadku rozłączenia. Nie zawiera żadnych informacji, które wymagają szyfrowania (ale, jak powiedziałem, nie mam przed sobą środowiska testowego, więc mógłbym się mylić). –

+0

@ScottChamberlain Dodałem treść procedury do pytania, aby można było ją zobaczyć. Rozumiem, że procedura składowana nie musi być szyfrowana, ale mam wymaganie stwierdzające, że musi być zaszyfrowane. Mógłbym odepchnąć, a klient mógłby zrobić dla mnie wyjątki, ale nie o to chodzi. – Rainbolt

+0

Czy próbowałeś Z SZYFROWANIE? – idstam

Odpowiedz

4

utworzyć wyzwalacz DDL, który sprawdza, czy tworzony jest procedura o nazwie typu „SqlQueryNotificationStoredProcedure-”, a jeśli tak, to natychmiast zmieniają WITH ENCRYPTION zamiast:

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; 

Zastrzeżenie: nie testowane na rzeczywistej notyfikacji zależności, ale podstawowa idea jest dobra. Jest dość kruchy, ponieważ zależy oczywiście od dokładnej formy procedury - dzięki czemu jest bardziej wytrzymały, ale nużący.

+0

To jest naprawdę miłe. Nie miałem pojęcia, że ​​można zmienić SQL podczas transportu. Rozważałoby usunięcie warunku '@Name LIKE 'SqlQueryNotificationStoredProcedure -%'', ponieważ jest zbędny. Przyjmuję tę odpowiedź, kiedy mam czas na sprawdzenie. – Rainbolt

+0

@Rainbolt: nie zmienia to dokładnie podczas transportu - procedura składowana jest naprawdę tworzona jako pierwsza, następnie wydawane jest oddzielne "ALTER", aby zmienić właśnie utworzoną procedurę przechowywaną. Efekt netto jest taki sam, ale różnica jest obserwowalna w przypadku inspekcji, replikacji i śledzenia profilu. –

+0

@Rainbolt: sprawdzanie nazwy nie jest dokładnie nadmiarowe, ponieważ przeprowadzamy zastępowanie tekstowe w procedurze, która zakłada, że ​​ma konkretny formularz. Dobrym pomysłem jest sprawić, by był jak najbardziej solidny (tzn. Być tak konkretnym, jak to tylko możliwe). W szczególności wyzwalacz ten nie powiedzie się, jeśli procedura składowana zawiera "AS \ nBEGIN" nigdzie indziej w tekście, co jest mało prawdopodobne, ale niemożliwe. Ale może jestem po prostu zbyt konserwatywny wobec tych rzeczy. :-) –

Powiązane problemy