Hallo,
ich habe bei meiner Webseite einen Admin-Bereich eingerichtet und seltsamer weise funktioniert das Attribut "[Authorize(Roles = "Administrator")]" am Controller nicht richtig. (Bzw. nicht wie erwartet)
Habe zum Testen auf der Startseite folgendes eingefügt:
@String.Join(", ", Roles.GetRolesForUser())
@Roles.IsUserInRole("Administrator")
Dies gibt mir für den aktuellen User "Access, Administrator" und "True" zurück.
möchte ich jetzt den Administratorbereich betreten, werde ich direkt auf die Login-Seite weitergeleitet.
In der Web.config habe ich folgende Einträge noch hinzugefügt:
<configuration>
<system.web>
<roleManager enabled="true" defaultProvider="SqlRoleManager" cacheRolesInCookie="true">
<providers>
<add name="SqlRoleManager" type="System.Web.Security.SqlRoleProvider" connectionStringName="DefaultConnection" applicationName="PAYP" />
</providers>
</roleManager>
</system.web>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
<remove name="RoleManager" />
</modules>
</system.webServer>
</configuration>
Jemand ne Idee, wo das Problem liegen könnte?
Gruß
Neokil
Davon abgesehen, dass ich Dir da pauschal nicht helfen kann les Dir mal folgenden Beitrag durch:
Don’t Do Role-Based Authorization Checks; Do Activity-Based Checks
Roles üner Authorize sind leider auch nicht im Berechtigungseinklang mit [Artikel] Drei-Schichten-Architektur weshalb sich das im neuen ASP.NET 6 auch bald konzeptionell ändern wird.
Man sollte bezogen auf die Web.Config Module erst entfernen und neue dann hinzufügen; nicht umgekehrt.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Verstehe ich das richtig: Es geht eig. darum, dass die Rollen nicht fest dem Authorize-Attribut festlegen soll, sondern ein eigenes Authorize-Attribut ableiten und dort die Authorisierung dynamisch erledigen?
Und wie sieht das dann aus, im Hintergrund benutze ich die Rollen für Nutzer usw. wie bisher, nur die benötigten Rollen für die Ausführung von Actions/Controllern werden nicht wie bisher dem Authorize-Attribut übergeben, sondern in der DB gespeichert und in der eigenen Authorize-Implementierung ausgelesen und geprüft?
Hatte den bisherige Mechanismus eigentlich nur deswegen übernommen, weil er sich bei der Standardvorlage anbietet.
Ich benutze das Authorize überhaupt nicht.
In meinen Controllern respektive in den Actions wird bei mir nichts anderes gemacht als ein Services abgefragt; der Service wiederum weiß ganz genau, welche Rolle der Benutzer benötigt.
Stell Dir vor die Ausführung willst Du nicht nur über ASP.NET machen, sondern zB über eine Konsolenanwendung; dann müsstest Du überall ein Rollensystem implementieren.
So; über einen eigenen Service, der das eigenständig prüft, ist das viel einfacher, modularer und spart auch noch ein Haufen an Code - und ist zudem testbar!
public ActionResult AddUser( AddUserViewModel user )
{
// ViewModel prüfen
// Modell anlegen
var user = new User(<daten von ViewModel übertragen);
try{
this.myUserService.AddUser(user);
}
catch(PermissionDeniedException e)
{
// Benutzer hat keine Rechte einen neuen Benutzer anzulegen
// Redirect
}
// Hat geklappt
}
public User AddUser(user)
{
// Prüfen, ob der aktuell ausführende Benutzer die nötigen Rechte hat
}
Die Standardvorlage ist an vielen Punkten nicht wirklich der Realität entsprechend empfehlenswert.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Sehe das wie Abt. Lager das in Services aus und prüfe das dort explizit. Als Zusatz, wenn man schon die Testbarkeit anspricht, verwende noch IoC/DI mit Ninject, Unity oder was auch immer. So hast du eine lose Kopplung und kannst besser Testen.
MVC6 bringt die DI-Funktionalität übrigens mit.
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Danke für die Hilfe, das komplette Auslagern in einen Service ist mir für dieses Projekt doch zu viel, da ich bis auf die Authorisierung alles schon so weit fertig habe. Werde mich aber beim nächsten Projekt daran versuchen.
ich habe mir jetzt an dem ersten Artikel orientiert und ein eigenes Authorisierungssystem gebaut, bei dem die Berechtigungen in eine DB ausgelagert werden.
Habe hierzu das "AuthorizeAttribute" abgeleitet, die AuthorizeCore entsprechend überschrieben und es dann bei den Globalen Filtern in der FilterConfig hinzugefügt.