Also baue ich eine benutzerdefinierte Sicherheitsbibliothek, die mit unserer Datenbank verbunden ist. Es soll eine grundlegende Zugangskontrolle für In-House-Apps bieten: Bestimmte Benutzer können X, andere nicht. Meine Bedürfnisse im Moment sind ziemlich einfach, aber die Bibliothek wird schließlich von mehreren Apps verwendet werden und eine Menge von sicherbaren steuern.
Mein grundlegendes Objektmodell ist, dass ein Benutzer ein Mitglied von null oder mehr Gruppen ist. Diese Gruppen gewähren null oder mehr Berechtigungen. In der Realität werden das alles Eins-zu-Viele sein, aber ich möchte das nicht durchsetzen. Berechtigungen sind nur gewährt (wenn keine Gruppen Ihnen die Berechtigung erteilen, haben Sie keine Berechtigung, aber es gibt kein "Ablehnen", das eine erteilte Berechtigung wie in Windows RBS außer Kraft setzt) und Gruppen können verschachteln (ein Tier 2-Benutzer) hat die Rechte eines Tier 1, plus einige neue). Wenn versucht wird, auf einen sicherungsfähigen Bereich des Programms zuzugreifen, wird die Anwendung zwingend bestätigen, dass ein Benutzer die erforderliche Berechtigung hat, indem er seine Gruppenhierarchie untersucht.
Ich möchte jedoch, dass mehrere Redundanzebenen in die Bibliothek integriert sind. Besonders wichtig ist, dass ein Benutzer, der keine Berechtigung zum Ändern von Sicherheitseinstellungen hat, nicht in der Lage ist. Daher möchte ich diese Sicherheitshierarchie in den meisten Fällen nur lesbar machen, sodass eine benötigte, aber verweigerte Berechtigung nicht im Speicher hinzugefügt werden kann. Nur wenn ein Benutzer nachgewiesen hat, dass er berechtigt ist, Sicherheitseinstellungen zu ändern, indem er einem schreibgeschützten Benutzer diese Berechtigung erteilt, sollten die Eigenschaften selbst auf Codeebene einstellbar sein.
Dort denke ich, dass ich es überbaut habe. Um dies zu tun, hat die Domäne eine gespaltene Persönlichkeit entwickelt; zwei Kopien von jedem der Objekte, eines schreibgeschützt, das andere nicht. Die Readonly-Version ist die standardmäßig erzeugte; Jede Operation, die eine beschreibbare Version erzeugt, erfordert, dass der aktuell angemeldete Benutzer berechtigt ist, Sicherheitsänderungen vorzunehmen. Dies führt zu zwei Benutzern (User und ConfigurableUser), zwei Groups, zwei Permissions mit jeweils zwei Interfaces (die konfigurierbaren stammen aus dem Readonly) ... Sie bekommen die Idee.
Ich habe festgestellt, dass die einzigen Leute, die diese Extra-Gruft stoppen, im Grunde andere Entwickler sind, die im Allgemeinen vertrauenswürdig sind (es ist eine Inhouse-App und wir kontrollieren alle Ressourcen, die diese App nutzt, und die Entwickler bekommen im Allgemeinen) Admin-Rechte für eine Menge). Wenn ich darauf vertrauen kann, dass Leute, die den Code berühren, wissen, was sie tun, können die Apps gelesen und geschrieben werden, und es gibt kein Problem mit der Möglichkeit, dass Berechtigungen mit einem cleveren Code-Snippet "erhöht" werden können. p>
Hilf mir, das vernünftig zu machen. Gibt es ein anderes Muster, dem ich folgen sollte? Habe ich recht, anderen Entwicklern zu misstrauen? Ich bevorzuge es, nicht mit Windows-Sicherheit zu integrieren, aber die Option wurde diskutiert; Der Hauptnachteil wäre, dass die Zugriffsrechte in Active Directory für das gesamte Unternehmen beibehalten würden und der Manager der Benutzer dieser App keinen solchen Zugriff auf die Gesamtsystemsicherheit hätte.
BEARBEITEN: Einige gute Kommentare und Antworten von allen. AD oder andere integrierte Sicherheit ist nicht völlig vom Tisch, aber wir haben darüber diskutiert, bevor ich anfing zu entwickeln, und einige Nachteile festgestellt. Also, hier sind ein paar meiner / unserer Gedanken darüber, warum wir uns sogar für ein "benutzerdefiniertes" Sicherheitssetup entschieden haben:
Die Nutzung der App erfolgt ausschließlich intern. Daher geht es bei der Sicherheit dieser App nicht so sehr um die Verhinderung von Angriffen von außen oder feindliche Übernahmen, sondern darum, Joe Officeworker davon abzuhalten, etwas zu tun, das er nicht geschäftspolitisch beachten sollte. Wenn Joe auf wundersame Weise einen Weg findet, sich selbst "Gott" in der App zu machen, sind seine Kräfte immer noch ziemlich begrenzt, da die App selbst nur sehr eingeschränkten Zugriff auf die Datenbank und andere Ressourcen hat, von denen er die meisten tun müsste Job sowieso und sind somit aufgrund der Tatsache, selbst der niedrigste Benutzer.
Trotzdem, wenn ein Benutzer jemals sein Windows-Passwort gecrackt, geknackt oder keylogged bekommen hat, würde der Angreifer durch die Anwendung "Free" seriösen Zugriff auf Client-Daten erhalten, wenn die App integrierte Sicherheit anstatt eines traditionellen verwendet Anmeldung. Eine separate Sicherheitsschicht für die App bietet zumindest eine Möglichkeit der Redundanz; Sie müssten zwei Gruppen von Anmeldeinformationen knacken, um an Stelle von einer zu gelangen, und diese zweite Gruppe von Anmeldeinformationen wird hinter einer weiteren Ebene der Datenbanksicherheit geschützt, für die der geknackte Benutzer keinen freien Zugriff hätte.
Die Verwendung von Active Directory oder einer anderen integrierten Sicherheit hat einige Probleme in Bezug auf die Entwicklung / Verwaltung.
Die einfache Lösung besteht darin, die Sicherheit innerhalb der Grenzen der App zu halten, anstatt an die Netzwerksicherheit anzuknüpfen. Wir bekommen eine Sicherheitsstruktur, die wir relativ einfach pflegen können, die bei der App aufhört.
BEARBEITEN SIE 2: Als ein Epilog zu dieser Frage war die Lösung, die ich schließlich fand, meine veränderbare Objekthierarchie beizubehalten, aber dann eine einfache Schnittstelle IAuthUser mit schreibgeschützten Mitgliedern für das Basiselement des Benutzers zu erstellen Infos und Berechtigungen. IAuthUsers werden an nur einer Stelle während der Anmeldung erstellt, indem der Benutzer, der mit den Anmeldeinformationen abgerufen wurde, in eine private Klasse kopiert wird, die die öffentliche Schnittstelle implementiert. Sie werden für die gesamte Authentifizierung und Autorisierung verwendet, indem die enthaltene Liste der Berechtigungen abgefragt wird, die beim Start von der Gruppenmitgliedschaft des Benutzers projiziert wurden. Sie werden niemals in veränderbare Benutzer zurückverwandelt und daher nie wieder in der Datenbank gespeichert. In der Zwischenzeit können die veränderbaren Benutzer nicht außerhalb des Anmeldeprozesses in IAuthUsers umgewandelt werden, sind also für die Autorisierung unbrauchbar und können nicht in der Datenbank gespeichert werden, ohne einen IAuthUser bereitzustellen, der über die Berechtigung verfügt, die Art der Änderungen im Objekt zu erkennen vergleicht es mit der Version, die derzeit in der Datenbank enthalten ist)
Statt eine geteilte Hierarchie zu haben, hätte ich die Berechtigung "Benutzer kann Sicherheitseinstellungen ändern" und bestätige das jederzeit, wenn ein Benutzer versucht, etwas zu bearbeiten.
" Komplexität ist der schlimmste Feind der Sicherheit. " - Bruce Schneier
Um ein sehr sicheres System aufzubauen, würde ich Active Directory für die unternehmensweite Zugangskontrolle einsetzen. Der wichtigste Teil Ihres vorgeschlagenen Sicherheitssystems ist, dass es nicht auf obskuren Funktionen basiert, um Angreifer zu täuschen. Stattdessen bedeutet die Verwendung von Active Directory, dass Ihr Zugriffssteuerungssystem aktiv von Microsoft verwaltet wird. Mit welcher Plattform sind Sie verbunden?
Diese Lösung ist nicht kugelsicher. Sie müssen sich immer noch Sorgen um LDAP-Injektion machen.
Ja, das klingt überbaut.
Es erscheint unnötig und zu komplex, die Objekte, die Ihre Rollen, Berechtigungen usw. definieren, auf der Grundlage der Sicherheit des Benutzers nicht zu ändern. Es sei denn, Sie haben eindeutig Anforderungen dafür.
Werden Sie zur Laufzeit nicht vertrauenswürdigen Plug-in-Code dynamisch laden? Warum dann die Schutzmechanismen für Code einfach Ihre Bibliothek verbrauchen.
Sie können sich auch andere Implementierungen von Autorisierungsbibliotheken ansehen und einige Hinweise daraus ziehen, wenn Sie sie nicht direkt verwenden können.
Zum Beispiel Rhino Security . Ayende hat eine Handvoll Blog-Posts darüber .
Das klingt eigentlich richtig.
Der Benutzer hat einen Kontext, der Dinge, die er geändert hat, im Auge behält. Wenn sie bereit sind, ihre Transaktion zu tätigen, durchläuft sie die Sicherheit, bevor sie ausgeführt wird. Offensichtlich gibt es einige Dinge, die Sie tun sollten, die ich einfach nicht getan habe, weil dies nur die 90-Sekunden-Ansicht dessen ist, woran ich denke, und ich werde das hacken, wenn Probleme auftauchen. Aber das ist der grundlegende Ansatz, den ich wählen würde.
%Vor%Tags und Links .net c# security architecture