AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Windows-Berechtigungen (Benutzer/Gruppen) im eigenen Programm verwenden

Windows-Berechtigungen (Benutzer/Gruppen) im eigenen Programm verwenden

Ein Thema von berens · begonnen am 23. Apr 2015 · letzter Beitrag vom 17. Aug 2015
Antwort Antwort
berens

Registriert seit: 3. Sep 2004
430 Beiträge
 
Delphi 2010 Professional
 
#1

Windows-Berechtigungen (Benutzer/Gruppen) im eigenen Programm verwenden

  Alt 23. Apr 2015, 10:49
Hallo zusammen!

Ich bilde mir ein schon die Suchfunktion genutzt zu haben, aber konnte leider keine Einsteiger-Freundlichen Infos erhalten, womit ich aktuell sinnvoll etwas anfangen könnte.

Das will ich in etwa machen: Siehe Anhang.

Ziel ist es, -mit dem Sicherheitssystem von Windows- die Benutzer/Gruppen von Windows (bei Einzelsystemen) bzw. ActiveDirectory in Domänen für bestimmte Funktionen in meinem Programm zu berechtigen bzw. zu sperren. So dürfen dann beispielsweise alle Personen einer Gruppe das Programm starten und Daten betrachten, bestimmte Benutzer allerdings nur Daten verändern oder löschen.

Es gelten die üblichen Bedingungen (und Einschränkungen): Benutzer dürfen das Programm auch dann starten, wenn Sie nicht namentlich in [meiner] Liste aufgeführt sind, sondern auch wenn Sie Mitglieder in einer oder mehrerer Gruppen sind, die diese Berechtigung haben.
Das Sicherheitssystem von Windows (Zumindesten in Bezug auf die Sicherheitsrechte von Dateien und Registry-Keys) sollte den Meisten hier bekannt sein.

Da mir das auf API-Ebene alles zu abstrakt ist verwendet ich die "Security Library" der Jedi-Komponenten: http://blog.delphi-jedi.net/security-library/

Bisherige, unter anderem verwendete Websites:
http://www.michael-puff.de/Programmi...kel/DACL.shtml (Danke Luckie!)
http://www.delphipraxis.net/86609-st...rogrammen.html
http://borland.newsgroups.archived.a...060121859.html

Leider ist es so, dass man mit der bei Jedi mitgelieferten Dokumentation nirgendwo "einsteigen" kann. Dort wird stets nur in Abkürzungen gesprochen und direkt auf der Startseite gesagt nach dem Motto "Ihr müsst euch mit dem Windows-Sicherheitssystem auskennen, um die Komponente nutzen zu können." Hmja... Ohne Einstiegspunkt kann man sich das schlecht beibringen...

In dem o.g. Tutorial zum Sicherheitsdialog wird zwar schön beschrieben, wie man die Zugriffsrechte von Dateien ändern kann, aber leider nicht, die das mit einem eigenen Objekt geht.

Klären wir vielleicht zunächst mal die Terminologie, korrigiert mich, wenn ich falsch liege:

DACL (discretionary access control list)
Ist letztendlich die Liste mit allen Benutzern und allen Rechten (und "Verweigerungen") für das Objekt, die Datei oder den Registrykey.

ACE (Access control entry)
Ist EIN Eintrag in der DACL, also z.B. "Gruppe A" darf die Datenbank bearbeiten oder "Gruppe Leiharbeiter" wird Bearbeiten verweigert. Eine DACL darf beliebig viele ACEs enthalten.
Wenn Benutzer "Alice" nun in "Gruppe A" ist, darf Sie also damit auch automatisch die Datenbank bearbeiten, es sei denn, Sie ist zusätzlich|stattdessen Mitglied in "Gruppe Leiharbeiter".


Korrektur: ACE ist ein RECHT, das immer nur für den aktuell ausgewählen Benutzer/Gruppe bearbeitet werden kann (z.B. "Lesen" oder "Schreiben")?

ACLEditor
Das Programm/Fenster aus dem Screenshot (siehe Anhang). Kann nativ über die Windows-API "EditSecurity(GetActiveWindow, Self)" aufgerufen werden.


Vorgehensweise:
Anhand eines Beispiels der Jedi-Komponenten habe ich mich zunächst für die "StringDescriptor"-Demo entschieden: rein optisch kommt diese meinem Vorhaben am Nächsten.

Der ACL Editor wird vorbereitet
Delphi-Quellcode:
  ACLEditor := TJwSecurityDescriptorDialog.Create(GetActiveWindow);
// ACLEditor.Flags := [sdfAdvanced, sdfEditDacl, sdfEditOwner, sdfEditEffective,
// sdfNoAdditionalPermission, sdfEditSacl];
  ACLEditor.Flags := [sdfEditSacl];
  ACLEditor.ObjectName := 'Beschreibung des Sicherheitsdialog DEMO';
  ACLEditor.ServerName := '';
Erzeugen der Instanz des Editors, setzen der Flags (welche Buttons sollen sichtbar sein, etc.) und der Titelleiste des Editors.

Für die Demo: Erzeugen von ein paar ACEs, damit schon mal ein paar Leute Berechtigungen haben, wenn wir mit der GUI vom Editor rumspielen:
Delphi-Quellcode:
  SecurityDescriptor := TJwSecurityDescriptor.Create;
  SecurityDescriptor.DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil,[],GENERIC_ALL,JwGuestsSID,True));
  SecurityDescriptor.DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil,[],GENERIC_READ,JwWorldSID,false));
  SecurityDescriptor.DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil,[],GENERIC_WRITE,JwLocalSystemSID,false));

  ACLEditor.SecurityDescriptor := SecurityDescriptor; // das Editor-GUI soll nun also ^-- diese Liste bearbeiten
Die Gruppe "Gäste" [meines PCs --> "JwGuestsSID"] darf alles machen, "Jeder" (JwWorldSID) darf nur lesen, und "SYSTEM" (JwLocalSystemSID) darf (nur) schreiben. Soweit so gut. Die Thematik der SIDs verstehe ich und soll hier nicht unnötiger Weise (?) näher beleuchtet werden. Parameter 3+4 habe ich also verstanden, der Rest ist noch eher unklar.

Nach dem Ausführen des Editors (if ACLEditor.ShowModal then) kann ich das Objekt SecurityDescriptor durchgehen und alle Einträge auslesen.

Wenn ich das richtig Verstanden habe, kann ich mir mit Memo1.Text := ACLEditor.SecurityDescriptor.GetSecurityDescriptorString(JwAllSiFlags) ;
diese komplette DACL als String zurückgeben lassen, in dem alle zugelassenen/verweigerten Benutzer(-SIDs) stehen, sowie die Berechtigungen, so dass ich diese z.B. in meiner Datenbank speichern, und beim nächsten Programmstart wieder auslesen kann (?).

Nur kommt der Punkt, an dem ich hänge:
Wie weise ich dem Dialog "zeilenweise" die Rechte zu, die der Benutzer bearbeiten können soll?
Als Optionen sollen nur "Zulassen" und "Verweigern" verwendet werden. (Oder nur "Zulassen", wenn das wesentlich einfacher ist.)

In der o.g. Demo "StringDescriptor" wird folgendes für diese zeilenweisen Rechte verwendet:
Delphi-Quellcode:
    Mapping := TJwSecurityGenericMappingClass(ComboBoxMapping.Items.Objects[ComboBoxMapping.ItemIndex]);
    ACLEditor.Mapping := Mapping; // zuweisung der o.g. Rechte an den Editor/GUI
ComboBoxMapping.Items.Objects[ComboBoxMapping.ItemIndex] bezieht sich hier in der Demo natürlich auf ein Objekt in einer ComboBox, die beim Programmstart befüllt wurde:
Delphi-Quellcode:
  ComboBoxMapping.Items.AddObject('Generic',Pointer(TJwSecurityGenericMapping));
  ComboBoxMapping.Items.AddObject('Process',Pointer(TJwSecurityProcessMapping));
  ComboBoxMapping.Items.AddObject('Threads',Pointer(TJwSecurityThreadMapping));
  ComboBoxMapping.Items.AddObject('Service',Pointer(TJwSecurityServiceMapping));
  ComboBoxMapping.Items.AddObject('FileFolder',Pointer(TJwSecurityFileFolderMapping));
Hier wird also EIN Pointer auf eine KLASSE (nicht ein instanziertes Objekt!) übergeben, welche -abgeleitet von TJwSecurityGenericMapping- die Klassen-Funktionen "GetMapping", "MapAccessMaskToString" und "GetAccessNames" bereitstellt. Je nach verlinkert Klasse sind in dem Editor also andere ACE-Zeilen zu sehen.
Der DACL-Editor kann sich also über diese Callback-Funktionen ein Kontanten/Konstantes(?) Array holen, in dem die einzelnen Zeilen (ACEs?) stehen. Beispiel für Datei/Ordner-Sicherheit im Windows-Explorer:
Delphi-Quellcode:
 FileFolderMapping: array[1..19] of TJwRightsMapping =
    (

    (Right: FILE_ALL_ACCESS; Name: 'Full control';
    Flags: SI_ACCESS_GENERAL or SI_ACCESS_SPECIFIC),
    (Right: FILE_GENERIC_READ or FILE_GENERIC_WRITE or FILE_GENERIC_EXECUTE or Delete;
    Name: 'Modify';
    Flags: SI_ACCESS_GENERAL or SI_ACCESS_SPECIFIC),
    (Right: FILE_GENERIC_READ or FILE_GENERIC_EXECUTE;
    Name: 'Read and execute';
etc.
Angenommen ich leite diese Klasse ab und erstelle mein statisches eigenes Array, sollte das ja dann klappen?

Die Frage ist nun halt auch noch, wie werden diese Werte abgespeichert, bzw. um was genau muss ich mich kümmern. Der DACL-Editor scheint ja selbst eine "Bit-Maske" zu erwarten, die er dann für jeden Benutzer/Gruppe füllen kann mit den Berechtigungen. Wie geht man das am schlausten an?

Wofür braucht der Editor
ACLEditor.OnSetSecurity := OnSetSecurity; In der Demo wird kommentarlos in OnSetSecurity die var-Variable bSuccess := true gesetzt...

Letztendlich: Wie prüfe ich, ob Benutzer "Alice" (bzw. deren SID) das Recht "Datenbank bearbeiten" hat, wenn in der DACL nur "Gruppe A" und "Gruppe Leiharbeiter" aufgeführt sind? (Annahme: Alice ist Mitglied in Gruppe A)

Vielen Dank im Voraus, vielleicht hilft mein Beitrag auch mal jemand anderem...


Edit1: Scheinbar geht es auch ohne das Konstanten-Array. Seine eigenen Berechtigungen kann man erstellen, indem man von TJwSecurityGenericMapping eine Klasse ableitet und bestimmte Funktionen überschreibt:
Delphi-Quellcode:
type
  TMySampleMapping = class(TJwSecurityGenericMapping)
  public
    class function GetMapping: TGenericMapping; override;
    class function GetBitMappingString(Idx: Cardinal): TJwString; override;
  end;

class function TMySampleMapping.GetBitMappingString(Idx: Cardinal): TJwString;
begin
  case idx of
    0: Result := 'Programm starten'; // Zeile 1 im ACL-Editor
    1: Result := 'Daten schreiben'; // Zeile 2
  else
    Result := 'DEMO ' + IntToStr(Idx); // Alle weiteren Zeilen, max. 32 insgesamt.
  end
end;

class function TMySampleMapping.GetMapping: TGenericMapping;
begin
  Result.GenericRead := READ_CONTROL or STANDARD_RIGHTS_READ;
  Result.GenericWrite := WRITE_DAC or WRITE_OWNER or Delete or ACCESS_SYSTEM_SECURITY or STANDARD_RIGHTS_WRITE;
  Result.GenericExecute := STANDARD_RIGHTS_EXECUTE or SYNCHRONIZE;
  Result.GenericAll := Result.GenericRead or Result.GenericWrite or
  Result.GenericExecute;
end;

//Im Hauptprogramm:
Mapping := TJwSecurityGenericMappingClass(Pointer(TMySampleMapping));
ACLEditor.Mapping := Mapping;
Die "GetMapping" Prozedur soll in der abgeleiteten Klasse unbedingt überschrieben werden. Warum?

Edit2:
So kann man die im Dialog eingestellten Optionen laden/speichern:
Delphi-Quellcode:
  // Speichern:
  if ACLEditor.ShowModal then // Dialog ausführen, und wenn mit "Ok" beendet:
  begin
    // Einstellungen/Auswahl in einem String speichern (hier: Memo1.Text)
    // diesen String kann man nun z.B. in der Datenbank speichern!
    Memo1.Text := ACLEditor.SecurityDescriptor.GetSecurityDescriptorString(JwAllSiFlags);
  end;

  // Laden:
  // hier muss der vorher gespeicherte Wert schon fertig drinnen geladen sein, sonst gibts Exception!
  SecurityDescriptor := TJwSecurityDescriptor.Create(Memo1.Text);
  ACLEditor.SecurityDescriptor := SecurityDescriptor;
Miniaturansicht angehängter Grafiken
dlg.jpg  

Geändert von berens (23. Apr 2015 um 11:31 Uhr)
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.415 Beiträge
 
Delphi XE5 Professional
 
#2

AW: Windows-Berechtigungen (Benutzer/Gruppen) im eigenen Programm verwenden

  Alt 14. Aug 2015, 15:34
Hast du hier Fortschritte gemacht? Läuft alles?

Ich würde den Dialog z.B. auch gerne nutzen, habe allerdings schon Probleme die SDL unter XE5 zu kompilieren.
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
430 Beiträge
 
Delphi 2010 Professional
 
#3

AW: Windows-Berechtigungen (Benutzer/Gruppen) im eigenen Programm verwenden

  Alt 17. Aug 2015, 12:49
Hallo generic,
ja, ich habe es gerade erst von ein paar Tagen geschafft.

Um andere Leute nicht dumm sterben zu lassen, und damit ich in ein paar Jahren auch eine Dokumentation habe habe ich meine Erkenntnisse als Tutorial verpackt, mit der Hoffnung auf Korrekturen und viele Ergänzungen:

http://www.delphipraxis.net/186242-w...verwenden.html

Fragen dazu beantworte ich gerne, falls ich kann. Falls ein neuer Thread aufgemacht wird, bitte kurz per PM anpingen.
  Mit Zitat antworten Zitat
Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#4

AW: Windows-Berechtigungen (Benutzer/Gruppen) im eigenen Programm verwenden

  Alt 17. Aug 2015, 17:23
Ich habe mal eine bescheidene Frage, was wäre ein Anwendungsbeispiel für eigene Windows-Berechtigungen ? Ich habe gerade keinerlei Vorstellung, wo das Thema zum Einsatz kommen könnte.
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Windows-Berechtigungen (Benutzer/Gruppen) im eigenen Programm verwenden

  Alt 17. Aug 2015, 17:34
Ich habe mal eine bescheidene Frage, was wäre ein Anwendungsbeispiel für eigene Windows-Berechtigungen ? Ich habe gerade keinerlei Vorstellung, wo das Thema zum Einsatz kommen könnte.
Nun man könnte z.B. eine Gruppe "DelphiNutzer" ins Leben rufen. Mitglieder dieser Gruppe haben dann die Berechtigung auf/in irgendeinem Verzeichnis (im Netz) zu arbeiten und gleichzeitig wird in Aufruf der IDE (Batch) geprüft, ob der angemeldete User auch Mitglied in "DelphiUser" ist.
(Es sollte klar sein, daß die Berechtigungen für Dateien/Verzeichnisse erst einmal definiert werden müssen)

Eigentlich sollte es auch reichen wenn das IDE-Verzeichnis im Zugriff beschränkt ist, aber da auch die Registry dieses Konzept nutzt, warum nicht auch direkt ein von uns erstelltes Programm?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
430 Beiträge
 
Delphi 2010 Professional
 
#6

AW: Windows-Berechtigungen (Benutzer/Gruppen) im eigenen Programm verwenden

  Alt 17. Aug 2015, 21:35
Naja, der von p80286 beschriebene Fall lässt sich bestimmt mit Dateiberechtigungen, Scripts etc. lösen, aber wenn man's mit Delphi prüfen kann/will, warum nicht...

Ich meinem Anwendungsfall geht es beispielhaft um folgendes:
Wir bieten für -auch große- Unternehmen ein Content-Management-System für öffentlich sichtbare Bildschirme an. Um nun die Verwaltung des Systems mit einer separaten Benutzerverwaltung (innerhalb der Software, Benutzername und Passwort werden aktuell "pseudo-verschlüsselt" abgespeichert) nicht unnötig für die Admins zu komplizieren, wünschen immer mehr Kunden eine Anbindung an Active-Directory (AD), also die Windows authentifiziert. Hier können ja Benutzergruppen weltweit standort-unabhängig gepflegt werden. Dies vermeidet Redundanz (Pflege der berechtigten Benutzer in Windows UND unserer Software), vereinheitlicht die Bedienung (Windows-Dialog mit allen Benutzern die es gibt, dank Domäne) und erhöht ggf. die Sicherheitheit, da wir keine Passwörter/Hashes mehr speichern müssen. Wenn man für jedes der folgenden Rechte eine AD-Benutzergruppe hat (kann ja auch die selbe sein), ist der Admin dankbar, weil er -ohne unsere Software zu installieren- die Berechtigungen jederzeit von seinem PC ändern kann.

Für uns gibt es nun folgenden konkreten Anwendungsfall, bei dem unterschiedliche Benutzer der Domäne unterschiedliches dürfen:
1) Hauptprogramm starten, Daten "Nur Lesen", bzw. "Login" in unsere Software (da darf ja nicht jeder reinschauen)
2) Text-Daten eintragen, ändern und löschen (z.B. Empfangsdamen, Pförtner)
3) Layoutgestaltung anpassen (Marketing)
4) Benutzerrechte anpassen (Administrator)
5) Wer darf auf welchen Bildschirm (unendlich viele!) zugreifen? Pförtner soll nur Bildschirm Pforte steuern, die Empfangsdamen nur den am Empfang, Marketing darf alle Bildschirme bespielen, etc.
6) Ggf. Ausblenden von Optionen, die der Benutzer nicht verwenden darf, um das GUI aufzuräumen (mal schauen...)

Klar, ich arbeite hier nicht mit Active-Directory-Objekten die ich manipulieren will, aber für mal eben im Programm zu sagen "Darfst Du" oder "Darfst du nicht" langt das. Sicher ist auch die Datenbank nicht manipulations-sicher, und man muss da ggf. serverseitig (z.B. auf SQL-Server, also nicht von uns!) mit Rechten nachhelfen, aber hier geht es eigentlich primär -man verzeihe mir den Ausdruck- um Vermeidung von Kollateralschaden durch versehentliche (oder absichtliche?) Falschbedienung im Programm, so dass z.B. nicht der Benutzer den falschen Bildschirm mit Inhalten bespielt.

Der Clou ist, dass wenn man keine Rechte festlegt, ja automatisch jeder alles darf (z.B. auf Einzel-PCs), so dass keinerlei Konfiguration notwendig ist.

Für weitere Rückfragen stehe ich gerne zur Verfügung.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:52 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz