In ASP.NET MVC können Sie eine Controller-Methode AuthorizeAttribute
wie folgt markieren :
[Authorize(Roles = "CanDeleteTags")]
public void Delete(string tagName)
{
// ...
}
Dies bedeutet, dass die Controller-Methode niemals aufgerufen wird, wenn sich der aktuell angemeldete Benutzer nicht in der Rolle "CanDeleteTags" befindet.
Leider für Fehler, AuthorizeAttribute
Rückkehr HttpUnauthorizedResult
, die immer HTTP - Statuscode zurückgibt 401. Dies bewirkt eine Umleitung auf die Login - Seite.
Wenn der Benutzer nicht angemeldet ist, ist dies absolut sinnvoll. Wenn der Benutzer jedoch bereits angemeldet ist, aber nicht die erforderliche Rolle innehat, ist es verwirrend, ihn an die Anmeldeseite zurückzusenden.
Es scheint, dass AuthorizeAttribute
Authentifizierung und Autorisierung miteinander verschmelzen.
Dies scheint in ASP.NET MVC ein kleines Versehen zu sein, oder fehlt mir etwas?
Ich musste eine kochen DemandRoleAttribute
, die die beiden trennt. Wenn der Benutzer nicht authentifiziert ist, gibt er HTTP 401 zurück und sendet sie an die Anmeldeseite. Wenn der Benutzer angemeldet ist, aber nicht in der erforderlichen Rolle ist, wird NotAuthorizedResult
stattdessen eine erstellt . Derzeit wird auf eine Fehlerseite weitergeleitet.
Sicher musste ich das nicht tun?
quelle
Antworten:
Bei der ersten Entwicklung hat System.Web.Mvc.AuthorizeAttribute das Richtige getan - ältere Revisionen der HTTP-Spezifikation verwendeten den Statuscode 401 sowohl für "nicht autorisiert" als auch für "nicht authentifiziert".
Aus der ursprünglichen Spezifikation:
In der Tat können Sie die Verwirrung genau dort sehen - es verwendet das Wort "Autorisierung", wenn es "Authentifizierung" bedeutet. In der täglichen Praxis ist es jedoch sinnvoller, einen 403 Forbidden zurückzugeben, wenn der Benutzer authentifiziert, aber nicht autorisiert ist. Es ist unwahrscheinlich, dass der Benutzer über einen zweiten Satz von Anmeldeinformationen verfügt, die ihm Zugriff gewähren - eine rundum schlechte Benutzererfahrung.
Betrachten Sie die meisten Betriebssysteme. Wenn Sie versuchen, eine Datei zu lesen, auf die Sie nicht zugreifen dürfen, wird kein Anmeldebildschirm angezeigt.
Zum Glück wurden die HTTP-Spezifikationen aktualisiert (Juni 2014), um die Mehrdeutigkeit zu beseitigen.
Aus "Hyper Text Transport Protocol (HTTP / 1.1): Authentifizierung" (RFC 7235):
Aus "Hypertext Transfer Protocol (HTTP / 1.1): Semantik und Inhalt" (RFC 7231):
Interessanterweise war das Verhalten von AuthorizeAttribute zum Zeitpunkt der Veröffentlichung von ASP.NET MVC 1 korrekt. Jetzt ist das Verhalten falsch - die HTTP / 1.1-Spezifikation wurde behoben.
Anstatt zu versuchen, die Weiterleitungen der Anmeldeseite von ASP.NET zu ändern, ist es einfacher, das Problem nur an der Quelle zu beheben. Sie können ein neues Attribut mit demselben Namen (
AuthorizeAttribute
) im Standard-Namespace Ihrer Website erstellen (dies ist sehr wichtig). Der Compiler übernimmt es dann automatisch anstelle des Standard- Attributs von MVC. Natürlich können Sie dem Attribut jederzeit einen neuen Namen geben, wenn Sie diesen Ansatz bevorzugen.quelle
filterContext.HttpContext.User.Identity.IsAuthenticated
, können Sie einfach prüfenfilterContext.HttpContext.Request.IsAuthenticated
, was mit eingebauten Nullprüfungen einhergehtFügen Sie dies Ihrer Login Page_Load-Funktion hinzu:
Wenn der Benutzer dort umgeleitet wird, aber bereits angemeldet ist, wird die nicht autorisierte Seite angezeigt. Wenn sie nicht angemeldet sind, fällt sie durch und zeigt die Anmeldeseite an.
quelle
if (User.Identity != null && User.Identity.IsAuthenticated) return RedirectToRoute("Unauthorized");
wo Unerlaubte ist eine definierte Routennamen.Ich dachte immer, das macht Sinn. Wenn Sie angemeldet sind und versuchen, eine Seite aufzurufen, für die eine Rolle erforderlich ist, die Sie nicht haben, werden Sie zum Anmeldebildschirm weitergeleitet, in dem Sie aufgefordert werden, sich mit einem Benutzer anzumelden, der über die Rolle verfügt.
Sie können der Anmeldeseite eine Logik hinzufügen, die überprüft, ob der Benutzer bereits authentifiziert ist. Sie können eine freundliche Nachricht hinzufügen, die erklärt, warum sie dort wieder verpfuscht wurden.
quelle
Leider haben Sie es mit dem Standardverhalten der ASP.NET-Formularauthentifizierung zu tun. Hier wird eine Problemumgehung (ich habe sie nicht ausprobiert) beschrieben:
http://www.codeproject.com/KB/aspnet/Custon401Page.aspx
(Es ist nicht spezifisch für MVC)
Ich denke, in den meisten Fällen besteht die beste Lösung darin, den Zugriff auf nicht autorisierte Ressourcen zu beschränken, bevor der Benutzer versucht, dorthin zu gelangen. Durch Entfernen / Ausgrauen des Links oder der Schaltfläche, die sie möglicherweise zu dieser nicht autorisierten Seite führen.
Es wäre wahrscheinlich schön, einen zusätzlichen Parameter für das Attribut zu haben, um anzugeben, wohin ein nicht autorisierter Benutzer umgeleitet werden soll. In der Zwischenzeit betrachte ich das AuthorizeAttribute als Sicherheitsnetz.
quelle
Versuchen Sie dies in Ihrem im Application_EndRequest-Handler Ihrer Global.ascx-Datei
quelle
Wenn Sie Aspnetcore 2.0 verwenden, verwenden Sie Folgendes:
quelle
In meinem Fall war das Problem "HTTP-Spezifikation verwendet Statuscode 401 sowohl für" nicht autorisiert "als auch" nicht authentifiziert "". Wie ShadowChaser sagte.
Diese Lösung funktioniert bei mir:
quelle