Beschränken Sie die Aktualisierung bestimmter Spalten. Nur gespeicherte Prozeduren dürfen diese Spalten aktualisieren

17

Ich habe sensible Preisspalten, die ich nur über eine gespeicherte Prozedur aktualisieren lassen möchte. Ich möchte, dass alle Code- oder manuellen Versuche, Werte in diesen Preisspalten zu ändern, fehlschlagen, wenn nicht die gespeicherten Prozeduren zum Aktualisieren verwendet werden.

Ich denke darüber nach, dies mithilfe von Triggern und einer Tokentabelle zu implementieren. Die Idee, über die ich nachdenke, ist eine Token-Tabelle. Die gespeicherten Prozeduren müssen zuerst Werte in die Tokentabelle einfügen. Aktualisieren Sie anschließend die Preisspalten. Der Update-Trigger prüft, ob das Token in der Token-Tabelle für die aktualisierte Zeile vorhanden ist. Wenn es gefunden wird, wird es fortgesetzt. Wenn das Token nicht gefunden wird, wird eine Ausnahme ausgelöst und die Aktualisierungstransaktion schlägt fehl.

Gibt es eine gute / bessere Möglichkeit, diese Einschränkung umzusetzen?

Elias
quelle
1
Sie können eine Ansicht für die spaltenbasierte Sicherheit verwenden. Das ist viel eleganter als ein Abzug. Erteilen Sie Benutzern die Berechtigung für die Ansicht, jedoch nicht für die zugrunde liegenden Daten.
Thomas Stringer
Das ist ein guter Punkt. Das Problem bleibt jedoch ungelöst, ohne viele Anwendungen zu beschädigen, die das Verbindungspooling verwenden.
Elias
Können Sie erklären, wie dies "viele Anwendungen zum Absturz bringen wird, die das Verbindungspooling verwenden"?
Aaron Bertrand

Antworten:

21

SQL Server ermöglicht Berechtigungen auf Spaltenebene. Nur zum Beispiel:

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

quelle
Vielen Dank an Michal, aber diese Lösung funktioniert bei mir nicht, da meine Anwendung eine Webanwendung ist, die das Verbindungspooling verwendet. Alle Benutzer stellen eine Verbindung mit derselben SQL Server-Verbindungszeichenfolge her.
Elias
1
@ Elias verstehe ich nicht. Die Verbindungszeichenfolge verbindet sich als bestimmter Benutzer, oder? Also SampleRolemit diesem Benutzer ersetzen ...
Aaron Bertrand
Berechtigungen auf Spaltenebene sind hier der richtige Weg. Dies und die Sicherstellung, dass die Entwickler wissen, dass Änderungen an den Werten über t-sql direkt das System zerstören.
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;
Aaron Bertrand
quelle
2

Wenn alle Ihre Benutzer das gleiche Login haben (autsch, BTW), dann ist hier eine andere Option

  • Aktualisierungsrechte dieses Benutzers (oder dieser Rolle, wenn Sie dies so tun) entziehen.
  • Ändern Sie den gespeicherten Prozess mit der Klausel "Als Eigentümer ausführen"
  • Dann wird der gespeicherte Prozess mit den Rechten des Benutzers ausgeführt, dem das Schema gehört, in dem er sich befindet dbo.

Den regulären Anwendungsbenutzern fehlen Aktualisierungsrechte für diese Tabelle, sodass sie sie auf keine andere Weise aktualisieren können.

SqlRyan
quelle
Sie müssen keinen neuen Benutzer erstellen, um dies zu tun ...
Aaron Bertrand
@aaronbertrand du hast recht - aus diesem Grund dachte e reasonni, du würdest "als Ersteller ausführen", aber das ist keine Sache - du kannst "als Eigentümer ausführen", solange der Benutzer, dem das Schema gehört, Rechte dazu hat Aktualisiere diese Tabelle. Befindet sich der gespeicherte Prozess in dbo, sind Sie abgesichert. Ich werde meine Antwort aktualisieren.
SqlRyan