Meine MVC-Anwendung verwendet die Rolle eines Benutzers an mehreren Stellen während einzelner Seitenanforderungen. Meine Frage ist, ob der Standard-SqlRoleProvider die aktuellen Benutzerrollen für die Lebensdauer einer Seitenanforderung zwischenspeichert?Wird der Rollenanbieter pro Anfrage zwischengespeichert?
Zum Beispiel habe ich die Verwendung von Rollen in Attributen auf Controller-Methoden machen:
[Authorize(Roles = "Admin")]
und benutzerdefinierten Code
if (user.IsInRole(MembershipRole.Admin))
{
// Do something
}
else if (user.IsInRole(MembershipRole.Printer))
{
// Do something else
}
Wenn die Rolle Provider nicht Rollen zwischenzuspeichern, ist die beste Lösung zu schreiben ein benutzerdefinierter Rollenanbieter, der von dem Standardrollenserver erbt und die Methoden überschreibt, um die Rollen einmal zu erhalten und sie für die Dauer der Anforderung zwischenzuspeichern? Kann dies so geschehen, dass sowohl das Autorize-Attribut als auch mein eigener Code die zwischengespeicherten Rollen nutzt?
(Falls Sie sich wundern, ich möchte nicht die cacheRolesInCookie web.config Option verwenden, um die Rollen in Cookies zwischenzuspeichern).
Vielen Dank im Voraus für Anregungen.
[Edit Details von Joe Antwort ausgelöst schließen]
I dekompilierten System.Web.Mvc.AuthorizeAttribute und die AuthorizeCore Methode die folgende Methode ruft für jede Rolle zu überprüfen:
httpContext.User.IsInRole
Wenn Sie dann in System.Web.Security.RolePrincipal schauen (was "Benutzer" oben ist), verwenden beide Methoden tatsächlich eine zwischengespeicherte Kopie der Benutzerrollen (oder füllen den Cache, wenn sie leer sind):
Der Cache wird als Feld auf Benutzer gespeichert, so dass seine Lebensdauer für die Dauer der Anforderung gilt. mit
Die Verfahren finden die Rollen:
Roles.Providers[this._ProviderName].GetRolesForUser(this.Identity.Name)
wird so verwenden, was Rollenanbieter Sie für die Anwendung gewählt haben (default oder custom).
Vielen Dank für Ihre Gedanken. Die MSDN-Dokumentation zu RolePrincipal sagt: "Wenn CacheRolesInCookie false ist, sucht das RolePrincipal-Objekt immer die Rollenmitgliedschaft mithilfe des Rollenanbieters." Wenn Sie sagen, RolePrincipal "caches Rollen für die Lebensdauer der Anfrage" kann ich fragen, wie Sie das wissen (Reflexion, SQL-Profiling, Dokumentation, etc.), wie es MSDN widersprechen scheint? – Appetere
@Steve, das weiß ich, indem ich mir die Implementierung (Lutz Reflector oder ILSpy) anschaue und auch die Erfahrung bei der Implementierung von Custom Providern. Dies widerspricht nicht MSDN: RolePrincipal sucht nach Rollenmodulen unter Verwendung des Rollenanbieters - es ruft RoleProvider.GetRolesForUser auf, ruft sie jedoch nur einmal pro Anforderung auf und speichert das Ergebnis in einem HybridDictionary-Feld. Der RoleProviderPrincipal von WCF ruft RoleProvider.GetRolesForUser nicht auf, sondern ruft immer RoleProvider.IsInRole auf und implementiert kein Zwischenspeichern von Rollen. – Joe
Danke dafür. Ich folgte Ihrem Ansatz und dekompilierte die relevanten Assemblys, um zu sehen, was tatsächlich passiert. Einige Details zu meiner ursprünglichen Frage hinzugefügt, um sie der Antwort hinzuzufügen. – Appetere