Laden...

Was ist der beste Weg für Autorisierung und Benutzerrechte im C# und WPF?

Erstellt von Zimling vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.847 Views
Z
Zimling Themenstarter:in
4 Beiträge seit 2020
vor 4 Jahren
Was ist der beste Weg für Autorisierung und Benutzerrechte im C# und WPF?

Einen wunderschönen guten Tag,

ich finde den Weg vor lauter Bäumen nicht. Ich bin noch recht neu in der CSharp-Welt und
bräuchte freundlicher Weise etwas Hilfe.

Ich würde gerne eine ordentliche Möglichkeit finden, Benutzerrechte in eine WPF-Anwendung
zu integrieren. Sprich der Benutzer muss sich anmelden und anhand der Rechte werden
ihm nur bestimmte Steuerelemente angezeigt (zum Beispiel Textboxen etc.).

Nun bin ich mir nicht sicher was der „beste“ Weg für dieses Unterfangen ist. Hätte der eine oder
andere einen Anreiz für mich? Ich hatte die Schlagwörter: ++IIdentity ++und ++IPrincipal ++im Internet gefunden
bin mir aber nicht sicher ob dies das Richtige ist.

Mir wäre auch noch wichtig, dass man nicht einfach nach dem initialisieren die Geschichten
auf die Sichtbarkeit „Collapsed oder Hidden" stellt sondern diese davor abfängt. Ist das mit
Xaml/Wpf eigentlich möglich?

Ich bitte den Umstand zu entschuldigen, wenn ich hier Falsch bin oder solch ein Thema schon existiert, da ich wie gesagt nicht genau weiß nach was ich suchen soll.

Vielen Dank im Vorraus.

16.825 Beiträge seit 2008
vor 4 Jahren

Da musste das Pferd von der richtigen Seite aufsäumen.

Was Du mit IPrincipal beschreibst ist die Implementierung. Was Du gar nich beschreibst ist, was und wie Du eigentlich Identity verwalten willst.

  • Was willst Du überhaupt authorisieren?
  • Über welche Wege müssen die Authentifizierungen und Authorisierungen erfolgen?
  • Geht es um ein lokales Auth? Geht es um Auth im weiteren Sinne innerhalb eines Unternehmens?
  • ....
    ...oder geht es NUR um die Authorisierung und den Rest hast Du? 🤔
    Für AuthZ gibts ja auch tausend verschiedene Wege.

Anders als bei der Authentifzierung, für die es fertige Frameworks und Services gibt, ist Authorisierung Applikationslogik und muss immer spezifisch implementiert werden.
Daher auch wenig Ahnung, was für eine Antwort Du erwartest 🙂

1.029 Beiträge seit 2010
vor 4 Jahren

Hi,

da dir offenbar noch jede Übersicht fehlt - nachfolgend einmal ein Link für eine Beispielimplementierung (bitte nur als Orientierungshilfe verwenden):
https://social.technet.microsoft.com/wiki/contents/articles/25726.wpf-implementing-custom-authentication-and-authorization.aspx

ACHTUNG:
Dort wird gezeigt, wie explizit auf bestimmte Rollen überprüft wird - das ist eigentlich längst überholt und auch oft nicht so flexibel wie man das in vielen Fällen gerne hätte. Grundlegend ist es meist gut zumindest auf Basis von Aktivitäten zu autorisieren. (siehe z.B. https://lostechies.com/derickbailey/2011/05/24/dont-do-role-based-authorization-checks-do-activity-based-checks/)

Ab davon bleibt aber die Frage:
Was genau gedenkst du in WPF abseits von bestimmten Ausblendungen zu erreichen?

Grundlegend sollten entsprechende Autorisierungsmechanismen natürlich nicht nur auf die Schicht der Oberfläche angewendet werden, sodass der User und dessen Rechte auch in anderen Schichten bekannt ist und genutzt wird. Letztlich führt das dann aber auch nur wieder dazu, dass bestimmte Sachen ausgeblendet sind 😉

LG

Z
Zimling Themenstarter:in
4 Beiträge seit 2020
vor 4 Jahren

Ich dank euch beiden erst einmal für die Antworten.

Erörterung:

Ich versuche etwas genauer zu werden, was ich eigentlich genau machen möchte.
Ich bin dabei für die Firma in der ich arbeite ein "kleines" Verwaltungsprogramm zu
schreiben. Vieleicht etwas eigennützig um mir meine Arbeit für die Zukunft zu erleichtern.

Dieses sollte mehrer Benutzerrollen darstellen können z.b:

  • Verwaltungsmitarbeiter
  • Außendiesntmitarbeiter

Sagen wir nun mal, dass die Anwendung, nach einer Benutzereingabemaske, aus zwei
Buttons(Lohnliste - Zugriffsrechte Verwaltung, Aufträge - Zugriffsrechte Außendienst) besteht.

Nun sollte verständlich sein, dass der Außendiesntmitarbeiter nicht auf die Lohnliste
zugreifen soll bzw. diese Möglichkeit ihm erst garnicht angezeigt wird. aber anders rum schon.
Dieses Prinzip soll quasi für sämtliche Handlungen im Programm greifen.

Grundlegend soll die Struktur der Anwendung wie folgt aussehen:

Der Benutzer startet das Programm und steht vor einer Eingabemaske für Benutzername und Passwort.
Nach der Eingabe der Daten sollen diese, auf einem lokalen Server im Büro, über eine Dankenbank(MariaDB/Sql)
Authentifiziert werden. Mir würde vorrerst auch eine Hartkodierte Liste reichen in der die Benutzer drien stehen.

Z.b in der art wie:

  • Name(Peter), Passwort(123), Benutzerrolle(Verwaltung).
  • Name(Maxim), Passwort(321), Benutzerrolle(Außendienst).

Später muss die Authentifizierung auch aus dem Internet klappen können,
dies ist aber erst mal nicht relevant und ein anderes Problem 😕.

Sobald der Benutzer sich also über diesen weg Authentifiziert hat, sollen lokal die
Authorisierungen greifen. Ich möchte quasi aus den bekommenen Daten der
Datenbank/Liste einen (abstrakten Benutzer?) erstellen. Dieser soll oder auch nicht code ausführen dürfen. Dieser soll oder auch nicht UI Elemente anzeigen/initialisieren dürfen.

Ich hoffe dass beantwortet etwas deine Fragen bzw beschreibt besser was ich erreichen möchte.

@Taipi88

Wieso ich möchte, dass die UI Elemente vor der dem erstellen abgefangen werden ist meinem kleinen Perfektionismus
verschuldet. Wenn der Außendiesntmitarbeiter sich anmeldet, kann ich nicht akzeptieren und es würde mich
schlaflose nächte kosten, dass der Button(Lohnliste) im Hintergrund geladen wird und dann ausgeblendet wird.
Weil meiner Meinung nach, dieser erst garnicht den Speicherplatz verbrauchen muss. 😕

Danke euch für eure Mühen.

16.825 Beiträge seit 2008
vor 4 Jahren

Ehrlich gesagt hat das mit Perfektionismus relativ wenig zutun; das erscheint Dir nur so.
In Wirklichkeit ist das sogar ganz weit weg von perfekt; denn es ist einfach ein relativ grober Konzeptfehler mit relativ großen Lücken im Gesamten.

Was Du das vor hast nennt man einen Monolithen; also eine Anwendung, die für "alles mögliche" verwendet werden soll, wie Du beschreibst Außendienst und Verwaltung.

Monolithen an für sich sind nicht pauschal schlecht - wenn man sie richtig einsetzt.
Doch die Realität zeigt, dass 99,9% aller Monolithen am Ende zu einem riesigen Monster an unübsichtlichen Code, Fehlern und Prozessproblemen heranwachsen.
Der Grund ist hier, dass die Firmen sich irgendwann dazu entscheiden, dass sie sich ein Tool schaffen, das eben alles mögliche "auf dem kurzen Dienstweg" schnell erledigen lässt; das wird dann immer weiter vollgeladen und irgendwann kommt der Punkt, an dem man was ordentliches braucht: und dann fällt das Kartenhaus zusammen.

Daher überlegt Dir gut, ob Du wirklich so ein Allrounder-Tool willst.

Aber zum eigentlichen Problem, mit dem Konzeptfehler.
Deine Anwendung greift direkt auf die Datenbank zu. Das heisst, dass Du quasi nur zwei Möglichkeiten hast, dass Du Berechtigungen kontrollieren kannst:

  • In der Client-Anwendung
  • In der Datenbank

Der Krux an der Sache ist, dass Du in der Datenbank prinzipiell eine gewisse Art von Authorisierung durchführen kannst; aber nicht wirklich granular - geschweige denn auf vom Taipi angesprochene Aktivitäten.
Eine Authorisierung in der Datenbank geht eben auf Daten (oder wenn schon fortgeschrittener aber seltener auf Ansichten).

Hast Du die Authorisierung nur in der Anwendung, dann hast Du das Problem, dass prinzipiell jeder einen vollständigen Kanal zur Datenbank hat, die potentiell eben keine Authorisierung besitzt.
D.h. wenn jemand eine Lücke in Deiner Anwendung findet, dann hat er uneingeschränkten Zugriff auf Deine Datenbank - und alle Daten.
Das ist immer noch die mit Abstand größte Datenlücke in Unternehmen im Jahr 2020.

Du hast bei dieser Art und Weise überhaupt keine Chance eine ordentliche, sichere Authorisierung zu gewährleisten; und das ist vermutlich auch das, worauf Taipi hinaus wollte: es bringt Dir 0,0 wenn Du ne einfache Sache in der UI ausblendest. Der Zugriff existiert (zumindest technisch) immer noch.
Alles was Du machst, ist bei so einer Architektur nur Verschleierung - weit, sehr weg von Perfektion.

Willst Du sowas "korrekt" umsetzen, dann kommst Du nicht wirklich um eine ordentliche Client-Server-Architektur drum herum.
Das heisst, dass Du eine Server Komponente hast (einen "Application Server") und eine Client Komponente. In so einem Szenario greift der Client nicht mehr direkt auf die Datenbank zu, sondern der Client fragt den Server nach den Daten.
Der Server ist nun in der Lage die Authorisierung durchzuführen und gibt dann dem Client die Informationen, die er haben soll.
Authorisierung ist dabei IMMER teil des Servers und nur OPTIONAL im Client.

Technisch funktioniert das abstrakt so:

  • Benutzer gibt im Client seine Credentials an (oder Du verwendest die Windows Identity/Active Directory)
  • Bei jeder Anfrage vom Client an den Server wird die Identität mitgeliefert (hier gibt es verschiedene Standards, von Kerberos über OAuth2 etc etc)
  • Der Server prüft ob der Benutzer für diese Anfrage überhaupt berechtigt ist
  • Wenn nicht, dann wird die Anfrage komplett abgelehnt
  • Wenn doch, dann kann der Server innerhalb einer Authorisierung granularer prüfen, ob der Benutzer für gewisse Aktionen, Daten etc berechtigt ist und darauf entsprechend reagieren und entweder alle gewünschte Daten herausgeben oder nur teile davon
  • Der Server selbst greift mit einem technischen Account auf die Datenbank zu

Die geläufigste Schnittstelle zwischen Client und Server basiert heutzutage auf HTTP und nennt sich REST: Representational State Transfer
REST hat an für sich verschiedene Ausbaustufen: Richardson Maturity Model

Die höchste Stufe HATEOS liefert dabei nicht nur Daten, sondern eben auch Zustände aus.
Dieser Mechanismus, der ehrlich gesagt jedoch relativ selten verwendet wird, kann nun dazu verwendet werden, Deine UI entsprechend der Informationen vom Server ein oder auszublenden:
Sind gewisse Informationen in einer Server-Antwort enthalten, dann blendest Du auch die entsprechenden UI Teile ein.
Alternativ kannst Du aber auch auf dem Client die Authorisierung erneut implementieren. Die führende Authorisierung ist aber immer der Server.

Das Vorhaben an für sich ist nicht komplex; dafür gibts alles fertige Frameworks und sowas ist quasi alles "Entwickleralltag".
Aber man muss es halt lernen 😉

M
368 Beiträge seit 2006
vor 4 Jahren

Weiterhin könnte man sich auch um andere Aspekte wie Funktionalität, Erweiterbarkeit,... bemühen. Siehe auch die Anmerkung von wg. Monolith (wobei auch Microservices geeignet koordiniert werden wollen). Zum Ansehen ein YT-Video von David Tielke: Arch. -Von Mono. bis Microservices

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

16.825 Beiträge seit 2008
vor 4 Jahren

Das Projekt hier, bei dem es sich um ein kleines Tool handelt, braucht sehr sehr wahrscheinlich keine Microservice-Plattform (wie ca. 90% der Projekte, die derzeit nicht wegen der Notwendigkeit sondern wegen dem Hype auf Microservices setzen).