ukulele-7
Goto Top

MSSQL Row Level Security (RLS) ohne Schema Binding?

Mahlzeit.

Ich habe ein konkretes Projekt wo ich Daten aus anderen Datenbanken, in denen ich nur lesen darf, dem Benutzer in einer Auswertungsdatenbank zugänglich machen will. Konkret sind das Zeiterfassungsdaten in einer View in der jeder nur Daten von sich selbst sehen soll. Perfekt um RLS auszuprobieren, dachte ich.

RLS scheint noch relativ neu, ich kann es auch erst seit dem Kauf des aktuellen MSSQL nutzen. Die Beiträge im Netz beschränken sich immer wieder auf das Wesentliche:
https://learn.microsoft.com/de-de/sql/relational-databases/security/row- ...
https://blog.netwrix.com/2019/06/27/how-to-implement-row-and-column-leve ...

Grundsätzlich lässt sich RLS auf Views anwenden, allerdings setzt RLS zwingend SCHEMABINDING voraus, was in meinem konkreten Fall natürlich nicht geht (ich herrsche nur über die Auswertungsdatenbank). Ich finde nichts im Netz dazu ob man das irgendwie abschalten oder "ignorieren" lassen kann. Ich meine der Benutzer selbst hat natürlich nicht das Recht die View anzupassen, damit sähe ich das ohne Schema Binding gar nicht als Sicherheitsproblem.

An dieser Stelle mal die Frage ob sich hier irgendjemand schon mit RLS in irgendeiner Form befasst hat oder vielleicht mal was zu dem Punkt Schema Binding gelesen hat. Vielleicht hat auch jemand einen anderen Lösungsansatz für mich.

Ich habe mir jetzt erstmal einen eigenen Lösungsweg gebastelt: Dabei verwende ich eine Tabelle Users, die in der Auswertungsdatenbank liegt. Diese Tabelle muss ich in Intervallen aus der eigentlichen Quelle aktualisieren. Auf diese wende ich RLS an, jeder sieht also nur seinen eigenen Datensatz in der einen statischen Tabelle. Alle Views auf die eigentlichen Daten der Quelle machen immer einen INNER JOIN mit dieser Tabelle - das funktioniert soweit wie gedacht.

Eigentlich finde ich den Weg auch sinnig, ich bin aber absolut noch nicht mit Dingen wie RLS vertraut. Da ich das an weiteren Stellen im Controlling verwenden möchte, gibt es einen besseren Weg?

Content-Key: 6922683529

Url: https://administrator.de/contentid/6922683529

Printed on: April 28, 2024 at 12:04 o'clock

Member: Dani
Dani Apr 26, 2023 at 16:53:17 (UTC)
Goto Top
Moin,
Grundsätzlich lässt sich RLS auf Views anwenden, allerdings setzt RLS zwingend SCHEMABINDING voraus, was in meinem konkreten Fall natürlich nicht geht (ich herrsche nur über die Auswertungsdatenbank).
SCHEMABINDING wird seitens SQL Server in Verbindung mit Views erzwungen. Hingegen bei Select Abfragen ist es optional.

Vielleicht hat auch jemand einen anderen Lösungsansatz für mich.
Leider nein. Wir lassen es durch die DBAs einrichten. face-wink


Gruß,
Dani
Member: Grinskeks
Grinskeks Apr 26, 2023 at 18:02:28 (UTC)
Goto Top
Moin,

dein aktueller Weg ist meines Erachtens auch der beste Weg.

Schemabinding ist leider nicht optional und legt Stolpersteine - für andere :D

Hast du eine View mit Schemabinding, sind enthaltene Objekte (Tabellen bzw. in der Query verwendete Spalten, Funktionen, Views) für Änderungen gesperrt.

Die Fehlermeldung ist dann etwas in der Art von "Änderung fehlgeschlagen weil eines oder mehrere Objekte auf die Spalte zugreifen".

RLS hat einen nicht unerheblichen Impact auf die Performance (Ausführungspläne ohne / mit RLS vergleichen).


Gruß
Grinskeks
Member: GrueneSosseMitSpeck
GrueneSosseMitSpeck Apr 26, 2023 at 18:13:04 (UTC)
Goto Top
schemabinding bewirkt eine "materialisierte Sicht". Das geht nur mit deterministischen Datentypen... und die View wird in einem Cache gespeichert, entweder in der MDF Datei oder im Arbeitsspeicher. Ansonsten ist RLS auch ein administrativer Albtraum.
Member: ukulele-7
ukulele-7 Apr 27, 2023 at 06:44:30 (UTC)
Goto Top
Ich verstehe die Funktion von Schema Binding, mir ist allerdings nicht ganz klar warum MS darauf besteht das eine View schemagebunden sein muss um darauf RLS zu machen. Das ist ja nur relevant wenn der User nicht nur Select Rechte bekommt sondern auch die Möglichkeit hat die View zu verändern. Aber gut, das ist wohl so zwingend gegeben.

Mein Workaround läuft eigentlich gut. Mit Performance habe ich allerdings auch noch minimal zu kämpfen, das liegt aber wohl mehr an einem CROSS JOIN im Select, der ist recht komplex. Interessanter Weise wird es langsamer wenn ich den Select vereinfache... Bin noch nicht sicher ob hier RLS mitverantwortlich sein kann. Die User Tabelle hat vielleicht 70 Einträge die unter RLS fallen und die werden dann auf etwa 35k Einträge gejoint. Idealerweise greift RLS dann bei der Abfrage nur auf die 70 Einträge, so denke ich mir das jedenfalls face-smile
Member: Grinskeks
Grinskeks Apr 27, 2023 at 07:48:53 (UTC)
Goto Top
Ich muss mich korrigieren:

Wenn die Policy mit Schemabinding = Off definiert ist, können auch die beteiligten Funktionen und Views ohne Schemabinding erzeugt werden.

Das hat aber auch einige Nachteile.

Dazu zählt unter anderem auch, dass Select und Execute Rechte für die zugreifenden User explizit für relational verwendete Objekte gecheckt werden, was bei Schemabinding = On ignoriert wird.

Administrativer Albtraum trifft es ganz gut.

Gruß
Grinskeks
Member: ukulele-7
ukulele-7 Apr 27, 2023 at 10:43:13 (UTC)
Goto Top
Danke @grinsekeks es scheint tatsächlich ohne SCHMABINDING zu gehen, ich kann das hier ausführen:
CREATE VIEW [dbo].[view_test]
AS
SELECT	'asdf' AS benutzeranmeldename,  
		1 AS daten;

CREATE FUNCTION [dbo].[predicate_function_test](@benutzeranmeldename SYSNAME)
RETURNS TABLE
--WITH SCHEMABINDING
AS
RETURN
SELECT	1 AS AccessRight
WHERE	1=0;

CREATE SECURITY POLICY filter_predicate_test
ADD FILTER PREDICATE [dbo].[predicate_function_test](benutzeranmeldename) ON dbo.view_test
WITH (STATE = ON, SCHEMABINDING = OFF);
Select bleibt dann leer weil 1=0 unwahr bzw. bei 1=1 werden alle Zeilen ausgegeben. Das mit den relationalen Objekten, die von der Sicht und somit dem User dann verwendet werden, muss ich erstmal testen. Theoretisch dürfte der Benutzer dann nichts sehen wenn er auf die eigentliche Datenquelle keine Rechte hat. Auch könnte das die Performance weiter mindern.