Wo passt die Autorisierung in eine Schichtenarchitektur?

24

Normalerweise trage ich Autorisierungsentscheidungen in meine serverseitigen Controller ein. Dies waren kürzlich RESTful-Endpunkte, aber ich denke, dasselbe gilt für MVC-Architekturen. Aus Gründen des Arguments wird davon ausgegangen, dass es sich um eine rollenbasierte Autorisierung handelt. Eine geschützte Methode wird mit Anmerkungen versehen oder überprüft und gegebenenfalls 403s zurückgegeben.

Angesichts der Tatsache, dass die Autorisierung tatsächlich eine Geschäftsregel ist - "Nur Administratoren können X auflisten", denke ich, dass sie eine Ebene nach unten verschoben werden sollten. Wenn ein Controller die Business-Schicht auffordert, den Vorgang auszuführen, teilt der Service oder die Business-Schicht dem Controller mit, dass er nicht autorisiert ist.

Ist das ein vernünftiger Ansatz? Gibt es Nachteile?

Ich hasse es, einen AuthorizationService zu haben, der im Wesentlichen eine Reihe statischer prozedural codierter Regeln enthält, aber vielleicht ist es sinnvoll, die gesamte Zugriffslogik an einem Ort zu belassen. Ist es ein Querschnittsthema, das getrennt werden sollte?

Ich frage also, ob jemand dies getan hat und wie er es auf saubere Weise erreicht hat oder ob es gute Ressourcen gibt, die ich lesen kann. Ich benutze Java fwiw, aber dies ist eine sprachunabhängige Frage.

Ich habe mir die zugehörigen Fragen hier angesehen und sie sind sehr dürftig und beantworten sie. Zum Beispiel: Validierung und Autorisierung in Domänenmodellen und Übertragen dieser Informationen über eine Service-Schicht an MVC

Ich lese die Sicherheitsdokumente von spring , die einige gute Argumente dafür liefern , dass es sich um ein Querschnittsthema handelt, aber ich mache mir Sorgen, dass es nur der "Frühlingsweg" ist, und ich hätte gerne weitere Perspektiven. Außerdem ist Ihre Anwendung an ein bestimmtes Framework gebunden.

tom
quelle
1
Status 403 ist wegen Berechtigungsproblemen falsch. Verwenden Sie 401.
gnasher729
@ gnasher729 Ich denke das ist rückwärts. 401 bedeutet, dass die Authentifizierung fehlgeschlagen ist oder nicht bereitgestellt wird, 403 bedeutet, dass Sie keine Zugriffsrechte haben: stackoverflow.com/questions/3297048/…
JimmyJames
@JimmyJames, es gibt eine andere Überlegung, dass Sie nur eine davon für alle Authentifizierungs- und Autorisierungsfehler verwenden sollten, da automatisierte Tools die Geschäftslogik nicht so einfach ableiten können. Es gibt einen gewissen Spielraum.
Berin Loritsch
1
@BerinLoritsch Entschuldigung, sagen Sie, dass die Idee darin besteht, es schwieriger zu machen, zu verstehen, ob es sich um ein Authentifizierungs- oder Autorisierungsproblem handelt? Der RFC scheint ziemlich klar zu sein, gibt jedoch an, dass Sie 404 anstelle von 403 verwenden können, wenn Sie nicht zu viele Informationen preisgeben möchten. Gibt es eine Referenz, die Sie als Argument für die Verwendung einer 401 anstelle von 403 angeben können?
JimmyJames
@ JimmyJames, ja. Dieser Denkprozess kommt von Sicherheitsexperten, nicht von Entwicklern. Und ich habe auch Ihre Empfehlung von 404 gesehen, die Informationen vollständig auszublenden, um zu verbergen, dass die Ressource überhaupt existiert.
Berin Loritsch

Antworten:

9

Es hat sich bewährt, nur die Optionen anzuzeigen, für die ein Benutzer berechtigt ist.

Dies zwingt die Autorisierung dazu, ein Querschnittsthema zu sein. Die "Ansicht" muss wissen, was ein Benutzer tun darf, bevor sie Optionen und Menüs für die Anzeige erstellen kann.

Das Back-End sollte nicht darauf vertrauen, dass das Front-End Sicherheitsentscheidungen trifft, und muss die Autorisierung selbst überprüfen.

Es kann Geschäftsregeln geben, die abhängig von den Daten eine Autorisierung bewirken, z. B. "Nur Benutzer mit einem Guthaben über 5000 USD können eine Fremdwährungsüberweisung durchführen" oder "Nur ein Benutzer in der Zentrale kann diese Konten anzeigen". Daher ist in der Geschäftslogik eine gewisse Berechtigungslogik erforderlich.

Es sind auch technische Berechtigungen zu berücksichtigen - wer darf die Protokolle anzeigen, wer kann die Datenbank sichern / wiederherstellen usw.

Letztendlich kann jede Komponente in Ihrem Unternehmen bestimmte Sicherheits- und / oder Autorisierungsanforderungen haben. In der Praxis ist es fast unmöglich, diese Anforderungen in eine separate "Autorisierungsschicht" zu packen.

James Anderson
quelle
7

Ich denke, es ist absolut vernünftig, die Autorisierung in Ihrer Service-Schicht einzubinden. Sie müssen Ihren Dienst vor nicht autorisierten Aktivitäten (insbesondere vor Datenänderungen) schützen. Ihre Service-Schicht könnte sich in einer Bibliothek befinden und von verschiedenen Präsentationsebenen verwendet werden (Sie könnten verschiedene UI-Anwendungen haben, die dieselbe Service-Schicht verwenden). Und Sie können sich nicht darauf verlassen, dass bestimmte Präsentationsebenen die erforderliche Validierung durchführen. Dies ist besonders wichtig, wenn Sie sich später dafür entscheiden, Ihre Service-Schicht in den separaten Prozess zu verschieben (z. B. nach dem SOA-Ansatz).

Nun darüber, wie dies auf "saubere Weise" erreicht werden kann. Die Idee, Geschäftslogik mit Berechtigungsprüfungen zu verunreinigen, gefällt mir nicht. Daher könnte eine bestimmte Implementierung des aspektorientierten Programmieransatzes hilfreich sein: Es könnte darin bestehen, Dienstmethoden mit speziellen Attributen auszustatten oder dynamische Proxys mit Interceptions zu verwenden.

Und was wichtig ist, ich muss zugeben, dass Sie in sehr einfachen Projekten möglicherweise ohne getrennte Validierungen leben könnten, nur um Ihr Leben zu vereinfachen. Aber es ist wichtig, dass Sie nicht den Moment verpassen, in dem aus einem "einfachen Projekt" ein "komplexes Projekt" wird.

ialekseev
quelle
7

Ich mag es, Berechtigungsprüfungen so niedrig wie möglich zu halten! (Aber nicht weiter!)

Es steht Ihnen weiterhin frei, automatisierte Autorisierungstests für Layer "darüber" zu schreiben. Und einige Regeln sind möglicherweise nur in höheren Ebenen anwendbar oder sinnvoll, z. B. in Ihrer Service-Ebene (CanView / CanSerialize?). Generell denke ich jedoch, dass die sicherste Autorisierungsstrategie auch die "DRY-est" -Strategie ist: Halten Sie die Autorisierung so niedrig wie möglich und verwenden Sie dabei den gängigsten oder gemeinsam genutzten Code (ohne die Authentifizierungsregeln zu komplizieren).

Denken Sie über die Alternative nach. Wenn Ihre Autorisierungsregeln nur in der Serviceebene getestet und durchgesetzt werden und Ihre schlechten Domänenobjekte den Willen eines launischen Serviceobjekts unterliegen, müssen Sie häufig jede einzelne Regel mehr als einmal, in mehreren Objekten und in mehreren durchsetzen Stellen in jedem Objekt und in komplizierteren Code.

Wenn Ihr Analytics-Team ein Beratungsunternehmen beauftragt, Berichtsdienste mit Ihren Domain-Objekten zu erstellen, müssen Sie diesen Entwicklern nicht vertrauen! (Oder was auch immer. Sie erstellen aus irgendeinem Grund zusätzliche Dienste oder rufen dieselben Objekte auf .) Sie möchten das große Buch der Geschäftsregeln nicht aufschlagen und hoffen , diese Regeln wieder ordnungsgemäß durchsetzen zu können . Sie möchten, dass Ihre Domain sie bereits kennt und umsetzt.

Svidgen
quelle
@Shoe Wenn ich Ihre Bedenken verstehe, ist das der springende Punkt. Wenn nur ein "Administrator" gemäß den Geschäftsregeln berechtigt ist, eine zu erstellen Widget, gilt überall dieselbe Regel. (Riskiert also nicht , dass jemand es im Stich gelassen ignorieren!) Wenn die Regel nicht funktioniert überall anwenden, es ist nicht wirklich eine Regel über Widgetsund nur Widgets . . Drücken Sie die Regeln so weit herunter, wie sie (die einzelnen Regeln) können. aber nicht so weit, wie "Regeln" gehen können ... Ich habe das Gefühl, dass ich die Unterscheidung nicht gut formuliere. Aber da sollte es Unterschiede geben.
Svidgen
Nach meiner Erfahrung sind Autorisierungsregeln häufig Teil der Geschäftsregeln. Als solches ist "so weit unten wie sie können" oft meine Domänenschicht. Aber ich vermute, dass es nur eine Konsequenz Ihrer Domäne ist, der Art der Regeln und der Art und Weise, wie das Geschäft über sie spricht.
Svidgen