Limitare l'aggiornamento su determinate colonne. Consenti solo la stored procedure per aggiornare quelle colonne


17

Ho colonne di prezzo sensibili che vorrei avere aggiornato solo tramite una procedura memorizzata. Vorrei che tutti i tentativi di codice o manuali di modificare i valori in queste colonne dei prezzi fallissero se non utilizza le stored procedure progettate per aggiornarlo.

Sto pensando di implementare questo utilizzando i trigger e una tabella token. L'idea che sto prendendo in considerazione è di avere una tabella token. le procedure memorizzate dovranno prima inserire i valori nella tabella token. Quindi aggiorna le colonne dei prezzi. Il trigger di aggiornamento verificherà se il token esiste nella tabella token per la riga aggiornata. Se trovato, continuerebbe. se il token non viene trovato, genererà un'eccezione e la transazione di aggiornamento fallirà.

Esiste un modo buono / migliore per attuare questa limitazione?


1
È possibile utilizzare una vista per la sicurezza basata su colonna. Sarà molto più elegante di un grilletto. Concedi agli utenti l'autorizzazione per la visualizzazione ma non i dati sottostanti.
Thomas Stringer,

Questo è un buon punto. Ma il problema rimane irrisolto senza interrompere molte applicazioni che utilizzano il pool di connessioni.
Elias,

Puoi spiegare come questo "interromperà molte applicazioni che utilizzano il pool di connessioni"?
Aaron Bertrand

Risposte:


21

SQL Server consente autorizzazioni a livello di colonna. Solo per esempio:

GRANT UPDATE ON dbo.Person (FirstName, LastName) TO SampleRole;
DENY UPDATE ON dbo.Person (Age, Salary) TO SampleRole;

Grazie Michal, ma questa soluzione non funzionerà per me perché la mia applicazione è un'applicazione Web che utilizza il pool di connessioni. Tutti gli utenti si connettono utilizzando la stessa stringa di connessione di SQL Server.
Elias,

1
@Elias non capisco. La stringa di connessione si collega come un utente specifico, giusto? Quindi sostituiscilo SampleRolecon quell'utente ...
Aaron Bertrand

le autorizzazioni a livello di colonna sono la strada da percorrere qui. Ciò e assicurando che gli sviluppatori sappiano che apportare modifiche ai valori tramite t-sql distruggerà direttamente il sistema.
mrdenny,

6
-- prevent your web app user from updating that column directly:

DENY UPDATE ON dbo.YourTable(Price) TO WebApplicationUserName;
GO

-- create a stored procedure while logged in as sysadmin:

CREATE PROCEDURE dbo.UpdateYourTable
  @ProductID INT,
  @Price DECIMAL(10,2)
WITH EXECUTE AS OWNER
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE dbo.YourTable 
    SET Price = @Price
    WHERE ProductID = @ProductID;
END
GO

-- grant explicit access only to that stored procedure to the web app user:

GRANT EXEC ON dbo.UpdateYourTable TO WebApplicationUserName;

2

Se tutti i tuoi utenti hanno lo stesso accesso (ouch, BTW), ecco un'altra opzione

  • revoca i diritti di aggiornamento da quell'utente (o ruolo, se lo stai facendo in questo modo).
  • Modifica il proc memorizzato con la clausola "esegui come proprietario" su di esso
  • quindi il proc memorizzato verrà eseguito con i diritti dell'utente proprietario dello schema in cui risiede (se presente dbo, allora sei già coperto).

I normali utenti dell'applicazione non avranno i diritti di aggiornamento per quella tabella, quindi non saranno in grado di aggiornarlo in altro modo.


Non è necessario creare un nuovo utente per fare questo ...
Aaron Bertrand

@aaronbertrand hai ragione - per questo motivo, ragionavo pensando che avresti fatto "esegui come creatore", ma non è una cosa - puoi fare "eseguire come proprietario" fintanto che l'utente che possiede lo schema aveva i diritti di aggiorna quella tabella. Se il proc memorizzato è in dbo, allora sei coperto. Aggiornerò la mia risposta.
SqlRyan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.