Abrufen des aktuellen Principals außerhalb der Webebene

8

Ich habe die folgende ntier App: MVC & gt; Dienstleistungen & gt; Repository & gt; Domain. Ich verwende die Formularauthentifizierung. Ist es sicher, Thread.CurrentPrincipal außerhalb meiner MVC-Ebene zu verwenden, um den aktuell angemeldeten Benutzer meiner Anwendung zu erhalten, oder sollte ich HttpContext.Current.User verwenden?

Der Grund, warum ich frage, ist, dass es Probleme mit Thread.CurrentPrincipal gibt, aber ich bin vorsichtig, einen Verweis auf System.Web außerhalb meiner MVC-Ebene hinzuzufügen, falls ich in der Zukunft ein nicht webbasiertes Fontende bereitstellen muss .

Aktualisieren

Ich habe den bis jetzt erhaltenen Rat befolgt, den Benutzernamen als Teil der Parameter an die aufgerufene Methode in den Dienst zu übergeben, und dies hat zu einer Verfeinerung meiner ursprünglichen Frage geführt. Ich muss überprüfen können, ob der Benutzer in einer bestimmten Rolle in einer Anzahl meiner Service- und Domain-Methoden ist. Es scheint ein paar Lösungen zu geben, die sich fragen, welcher der beste Weg ist, um fortzufahren:

  1. Übergeben Sie den gesamten HttpContext.Current.User als Parameter und nicht nur den Benutzernamen.
  2. Rufen Sie Thread.CurrentPrincipal außerhalb meiner Web-Ebene auf und verwenden Sie diese. Aber wie stelle ich sicher, dass es gleich HttpContext.Current.User ist?
  3. Bleiben Sie bei der Eingabe des Benutzernamens wie bisher vorgeschlagen und verwenden Sie dann Roles.IsUserInRole. Das Problem bei diesem Ansatz besteht darin, dass ein Verweis auf System.Web erforderlich ist, was außerhalb meiner MVC-Schicht nicht korrekt ist.

Wie würden Sie vorschlagen, ich fahre fort?

    
James 18.07.2012, 14:37
quelle

5 Antworten

2

Ich würde das auch nicht tun, HttpContext.Current.User ist spezifisch für Ihre Webschicht.

Warum nicht den Benutzernamen in Ihre Service-Ebene einfügen?

    
Joe Ratzer 18.07.2012, 14:39
quelle
2

Ordnen Sie die relevanten Benutzerdetails einem neuen Class zu, um den LoggedInUser darzustellen, und übergeben Sie diesen als Argument an Ihre Business-Schicht-Methode

%Vor%

Legen Sie nun die Werte fest und übergeben Sie diese an Ihre BL-Methode

%Vor%     
Shyju 18.07.2012 14:41
quelle
2

Sie sollten Ihre Benutzerinformationen so abstrahieren, dass sie nicht von Thread.CurrentPrincipal oder HttpContext.Current.User abhängt.

Sie könnten beispielsweise einen Konstruktor oder einen Methodenparameter hinzufügen, der einen Benutzernamen akzeptiert.

Hier ist ein übermäßig vereinfachtes Beispiel für einen Konstruktorparameter:

%Vor%     
jrummell 18.07.2012 14:39
quelle
2

Ich bevorzuge Option Nummer 2 (verwende Thread.CurrentPrincipal außerhalb der Web Tier). Da dies nicht Ihre Service-Tier polieren & amp; Daten Tier Methoden. mit Boni: Sie können Ihre Rollen und zusätzliche Informationen im benutzerdefinierten Prinzipal speichern;

Stellen Sie sicher, dass Thread.CurrentPrincipal in Ihrer Service- und Datenebene mit Ihrer Webebene übereinstimmt. Sie können Ihren HttpContext.Current.User (Context.User) in Global.asax (Application_AuthenticateRequest) festlegen. Andere alternative Orte, an denen Sie dies einstellen können, werden unten hinzugefügt.

Beispielcode:

%Vor%

Natürlich müssen Sie zuerst Ihr Login-Formular implementieren, um Autorisierungs-Cookies zu erstellen, die Ihren benutzerdefinierten Prinzipal enthalten.

Application_AuthenticateRequest wird für jede Anfrage an den Server ausgeführt (CSS-Dateien, Javascript-Dateien, Bilddateien usw.). Um diese Funktionalität nur auf die Controller-Aktion zu beschränken, können Sie versuchen, den benutzerdefinierten Prinzipal in ActionFilter zu setzen (ich habe das nicht versucht). Was ich versucht habe, ist das Setzen dieser Funktionalität in einem Interceptor für Controller (ich benutze Castle Windsor für meine Dependency Injection und Aspect Oriented Programming).

    
kite 29.08.2012 04:55
quelle
1

Ich glaube, dass Sie auf dieses Problem stoßen, weil Sie die Verantwortlichkeit Ihrer Domains weiter einschränken müssen. Es sollte nicht in der Verantwortung Ihres Dienstes oder Ihres Dokuments liegen, die Autorisierung zu übernehmen. Diese Verantwortung sollte von Ihrer MVC-Schicht übernommen werden, da der aktuelle Benutzer in Ihrer Web-App und nicht in Ihrer Domäne angemeldet ist.

Wenn Sie versuchen, den aktuellen Benutzer von Ihrem Dienst oder Dokument aus zu suchen, führen Sie die Überprüfung in Ihrer MVC-App aus. Sie erhalten dann etwa Folgendes:

%Vor%

Das ist sauber, leicht zu lesen und ermöglicht es Ihnen, Ihre Dienste und Domain-Klassen von Autorisierungsbedenken freizuhalten. Sie können Roles.IsUserInRole("DocumentEditorRole") immer noch Ihrem Ansichtsmodell zuordnen. Das einzige, was Sie verlieren, ist die CurrentUserCanEdit-Methode für Ihre Document-Klasse. Wenn Sie jedoch an Ihr Domänenmodell denken, das reale Objekte darstellt, gehört diese Methode ohnehin nicht zum Dokument. Sie könnten es sich als Methode für ein Domain-Benutzerobjekt vorstellen ( user.CanEditDocument(doc) ), aber alles in allem denke ich, dass Sie glücklicher sein werden, wenn Sie Ihre Berechtigung nicht in Ihrer Domain-Ebene behalten.

    
rusmus 07.01.2013 06:07
quelle