Laden...

[Gelöst] MS SQL - Zugriffsberechtigung auf Datensatzebene möglich?

Erstellt von SlyFox vor 13 Jahren Letzter Beitrag vor 13 Jahren 4.953 Views
S
SlyFox Themenstarter:in
231 Beiträge seit 2007
vor 13 Jahren
[Gelöst] MS SQL - Zugriffsberechtigung auf Datensatzebene möglich?

verwendetes Datenbanksystem: MS SQL Server 2008 Express

Hallo,

ich soll eine Lotus Notes Anwendung auf C# und SQL-Server portieren. Das traue ich mir generell auch zu.

In Lotus Notes wird die Sichtbarkeit von Datensätzen über ein Readers-Feld geregelt. Wer namentlich in diesem Feld aufgelistet wird, sieht den Datensatz. Für alle anderen Benutzer ist er nicht zu sehen.

Wie löst man das in MS SQL? Ein Stichwort zu dem Thema würde mir schon reichen.

Vielen Dank

Christoph

M
368 Beiträge seit 2006
vor 13 Jahren

Stichwort: Objektberechtigung
Vgl. auch mit Buch: SQL Server 2008 - Der schnelle Einstieg, Kapitel 9

Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉

S
SlyFox Themenstarter:in
231 Beiträge seit 2007
vor 13 Jahren

Hallo M.L.,

danke für die Info. Ist wohl doch nicht so einfach, einzelne Datensätze in einer SQL-Datenbank vor unberechtigtem Zugriff zu schützen.

Wer kann mir weitere Bücher zu diesem Thema empfehlen?

Christoph

L
770 Beiträge seit 2006
vor 13 Jahren

Naja einfach, wenn du sowas machen möchtest musst du ja die Benutzer kennen, also was hindert dich daran, so eine "readers" Spalte selbst zu erzeugen und dementsprechend abzufragen?

lg Lion

3.511 Beiträge seit 2005
vor 13 Jahren

Moin,

das MS CRM geht da einen recht interessanten Weg (den ich allerdings selber auch einsetze). Alle Entities, die fähig sind Rechte zu verwalten, greifen auf ein und die selbe Tabelle zu. In dieser Tabelle sind die Berechtigungen für den einen Datensatz vorhanden.

Also z.B.


Person                     Company
--------                   --------
ID          Guid           ID        Guid
LastName    NVarChar       Name1     NVarChar
FirstName   NVarChar       Name2     NVarChar

Permissions
--------
ID          Guid
EntityID    Guid
UserID      Guid
AccessRight Int  (Flag-Enum)
usw...

Das AccessRight kann Dinge wie Read, Write, Delete, Print, Share usw. enthalten. Den Vorteil den du hier hast ist, dass du verschiedenen Personen auch verschiedene Rechte geben kannst. Sollte es nur eine Spalte "Reader" (oder so) geben, hat genau eine Person das Recht auf diesen Datensatz. Was ist, wenn einer nur lesen darf, ein anderer aber nur schreiben? Dann hast du verloren 😃

Bei den oberen Weg, gibt es auch zwei Varianten
a) Implizit
Jede Berechtigung muss angegeben werden, für jeden Benutzer.
Vorteil: Man hat von vorneherein die komplette Kontrolle über jeden Datensatz.
Nachteil: Liegt ja auf der Hand. Pro Entity, gibt es mindestens einen Datensatz. D.h. bei 10 Firmen und 10 Personen hat man schon 20 in der Tabelle.
b) Explizip
Jeder Benutzer hat alle Rechte, nur die Einschränkungen werden in die Tabelle geschrieben.
Vorteil: In der Tabelle Berechtigungen steht nur das drin, was wirklich nötig ist.
Nachteil: Man muss die Rechte in der Software im nach hinein explizit vergeben. Das kann für die Benutzer verwirrend sein.

Das ist jetzt nur das Benutzerrechte-Verwatung gedöns. Benutzerrollen kommen auch noch hinzu. Wenn es dich also interessiert, kann ich das auch nochmal zusätzlich aufführen.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

S
SlyFox Themenstarter:in
231 Beiträge seit 2007
vor 13 Jahren

Hallo,

@Lion1984: Meinst du eine SELECT Anweisung, wo im WHERE abgefragt wird, of das Readers-Feld einen bestimmten Benutzernamen enthält? Wie kann ich dann dafür sorgen, dass diese WHERE Klausel nicht manipuliert wird?

@Khalid: Auch an dich die Frage: wie kann man das manipulationssicher machen?

Ich dachte eher an eine Lösung, die direkt auf dem Server greift und demnach nicht manipuliert werden kann.

Christoph

3.511 Beiträge seit 2005
vor 13 Jahren

Was genau meinst du mit manipulieren? Die User werden doch kein direkten Zugriff auf die DB haben, oder? Sowas läuft über ein Frontend (Win, Web). Die normalsterblichen User sollten nie die Möglichkeit haben eigene SELECTs abzufeuern. Und wenn dann über eine Abstraktionsschicht, die solche Zugriffe automatisch absichert. An sich bist du als Entwickler dafür Verantwortlich, das nichts manipuliert werden kann.

Arbeitest du mit Domänensicherheit, kannst du sowas über VIEWs absichern, in dem du die Funktionen wie z.B. SUSER_NAME() verwendest und die User nur Berechtigungen auf die VIEWs haben.

Interessant für sich ist vielleicht auch das hier: Implementing Row- and Cell-Level Security SQL Server 2005

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

L
770 Beiträge seit 2006
vor 13 Jahren

Die Antwort wurde ja bereits gegeben, aber:

Wenn es dich also interessiert, kann ich das auch nochmal zusätzlich aufführen.

Mich würde das durchaus interessieren 😃

lg Lion

S
SlyFox Themenstarter:in
231 Beiträge seit 2007
vor 13 Jahren

Hallo,

@Khalid: Danke vielmals. Ich werde das jetzt mittels Views und SUSER_NAME() lösen.

Christoph

3.511 Beiträge seit 2005
vor 13 Jahren

@Lion1984:
Die Rollenimplementierung dazu ist eigentlich relativ einfach. Dazu drösel ich mal das Schema auf, welches ich schon gepostet habe:


Person                     Company
--------                   --------
ID          Guid           ID          Guid
LastName    NVarChar       Name1       NVarChar
FirstName   NVarChar       Name2       NVarChar
OwnerUserID Guid           OwnerUserID Guid
OwnerRoleID Guid           OwnerRoleID Guid

Permissions
--------
ID          Guid
EntityID    Guid
UserID      Guid
AccessRight Int  (Flag-Enum)

Roles
--------
ID           Guid
Name         NVarChar

Wenn ein Datensatz angelegt wird (z.B. Person), bekommt der Datensatz a) den Benutzer verpasst, der den Datensatz angelegt hat (dieser hat volle Zugriffsrechte) und b) die Rolle verpasst, in dem der User sich momentan befindet. Beides muss hinterlegt sein, da der Benutzer der den Datensatz angelegt hat, seine Rolle wechseln könnte aber der Datensatz weiterhin nur für die Rolle sichtbar sein soll. Oder die zugehörige Rolle gewechselt wird (wenn dies überhaupt möglich sein soll).

So, und jetzt kann man überlegen wie man weiter vorgeht. Im meinem Fall ist es so, das nur die User die Datensätze überhaupt sehen, die zur gleichen Rolle gehören*. Soll ein anderer Benutzer aus einer anderen Rolle diesen Datensatz ebenfalls sehen, so muss das Recht explizit an den Benutzer gehängt werden (das ist das Share Rechte, welches ich unten erwähnt habe).

Ebenfalls muss man sich aussuchen, welche Berechtigungen die User aus der gleichen Rolle wie die OwnerRoleID haben. Ebenfalls Vollzugriff, oder Eingeschränkt? Je nach Wahl wird dann entsprechend die Permissions Tabelle gefüllt (und dann auch je nach Typ (Explizit/Implizit)).

Man sieht, das ganze wirkt recht komplex. Man bekommt aber so wirklich die volle Kontrolle über die einzelnen Datensätze und kann damit eigentlich fast alle Kundenwünsche abbilden. Allerdings muss ein bewusst sein, dass solch ein System schnell in die Knie gehen kann, wenn man Indizes falsch oder gar nicht setzt. Denn bei eigentlich jedem! Zugriff, wird auf die Permission Tabelle gejoint.

Achja, man kann das ganze sogar noch weiter treiben. Mal angenommen der Kunde wünscht sich zudem, das nur bestimmte User Daten auf der Oberfläche sehen wollen (also Cell-Based Security). Sowas lässt sich exakt genau so Abbilden. Einfach eine Tabelle FormPermissions einbauen und für die Form eigene Rechte vergeben (z.B. ReadWrite, ReadOnly, Visible). Dann wird es allerdings erst richtig witzig 😃

*Was ich hier nicht gezeigt habe ist, dass die Rollen hierahisch sein können. Die Tabelle Roles hat also noch eine ParentRoleID. Hier muss man dann nur entscheiden, ob die oberste, oder die unterste Rolle gewinnt (für die OwnerRoleID).

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)