Frage

Ich schreibe eine App mit asp.net-mvc, die auf iis6 bereitgestellt wird.Ich verwende die Formularauthentifizierung.Wenn ein Benutzer versucht, ohne entsprechende Autorisierung auf eine Ressource zuzugreifen, möchte ich normalerweise, dass er auf eine Anmeldeseite umgeleitet wird.FormsAuth macht das für mich ganz einfach.

Problem:Jetzt habe ich eine Aktion, auf die eine Konsolen-App zugreift.Was ist der schnellste Weg, diese Aktion mit dem Status 401 reagieren zu lassen, anstatt die Anfrage auf die Anmeldeseite umzuleiten?

Ich möchte, dass die Konsolen-App auf diesen 401-Statuscode reagieren kann, anstatt dass er transparent ist.Ich möchte auch die Standardeinstellung beibehalten und nicht autorisierte Anfragen zum Verhalten der Anmeldeseite umleiten.

Notiz:Als Test habe ich dies zu meiner global.asax hinzugefügt und es hat die Formularauthentifizierung nicht umgangen:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    HttpContext.Current.SkipAuthorization = true;
}

@Dale und Andy

Ich verwende den in MVC Preview 4 bereitgestellten AuthorizeAttributeFilter.Dies gibt ein HttpUnauthorizedResult zurück.Dieses Ergebnis setzt den StatusCode korrekt auf 401.So wie ich es verstehe, besteht das Problem darin, dass asp.net die Antwort abfängt (da sie als 401 markiert ist) und zur Anmeldeseite umleitet, anstatt sie einfach durchzulassen.Ich möchte dieses Abfangen für bestimmte URLs umgehen.

War es hilfreich?

Lösung

Ok, ich habe das umgangen.Ich habe ein benutzerdefiniertes ActionResult (HttpForbiddenResult) und einen benutzerdefinierten ActionFilter (NoFallBackAuthorize) erstellt.

Um eine Umleitung zu vermeiden, markiert HttpForbiddenResult Antworten mit dem Statuscode 403.FormsAuthentication fängt mit diesem Code keine Antworten ab, sodass die Anmeldeumleitung effektiv übersprungen wird.Der NoFallBackAuthorize-Filter prüft, ob der Benutzer autorisiert ist, ähnlich wie der enthaltene Authorize-Filter.Der Unterschied besteht darin, dass HttpForbiddenResult zurückgegeben wird, wenn der Zugriff verweigert wird.

Das HttpForbiddenResult ist ziemlich trivial:

public class HttpForbiddenResult : ActionResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        context.HttpContext.Response.StatusCode = 0x193; // 403
    }
}

Es scheint nicht möglich zu sein, die Umleitung der Anmeldeseite im FormsAuthenticationModule zu überspringen.

Andere Tipps

Könnte ein Kunststück sein (und möglicherweise nicht einmal funktionieren), aber sehen Sie auf Ihrer Anmeldeseite nach, ob Request.QueryString["ReturnUrl"] != null und wenn ja, einstellen Response.StatusCode = 401.

Bedenken Sie, dass Sie Ihre Konsolen-App trotzdem dazu bringen müssen, sich irgendwie zu authentifizieren.Sie erhalten die HTTP-Basisauthentifizierung nicht kostenlos:Sie müssen Ihre eigenen rollen, aber es gibt viele Implementierungen.

Haben Sie Ihr eigenes FormsAuth-Attribut für die Aktion geschrieben?Wenn ja, wird Ihnen in der OnActionExecuting-Methode der FilterExecutingContext übergeben.Damit können Sie den 401-Code zurückgeben.

public class FormsAuth : ActionFilterAttribute
{
    public override void OnActionExecuting(FilterExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.StatusCode = 401;
        filterContext.Cancel = true;
    }
}

Das sollte funktionieren.Ich bin nicht sicher, ob Sie das FormsAuth-Attribut geschrieben haben oder es von woanders erhalten haben.

Ich habe das AuthorizeAttribute, das in Preview 4 enthalten ist, noch nicht verwendet.Ich habe mein eigenes gerollt, weil ich das MVC-Framework seit dem ersten CTP verwende.Ich habe einen kurzen Blick auf das Attribut in „reflector“ geworfen und es macht intern das, was ich oben erwähnt habe, mit der Ausnahme, dass das hexadezimale Äquivalent von 401 verwendet wird.Ich muss im Aufruf weiter oben nachsehen, um zu sehen, wo die Ausnahme abgefangen wird, denn höchstwahrscheinlich wird dort die Umleitung durchgeführt.Dies ist die Funktionalität, die Sie überschreiben müssen.Ich bin mir nicht sicher, ob Sie es schon können, aber ich werde es zurückschicken, wenn ich es gefunden habe, und Ihnen einen Workaround geben, es sei denn, Haacked sieht das und postet es selbst.

Ich habe ein wenig gegoogelt und Folgendes herausgefunden:


    HttpContext.Current.Response.StatusCode = 401;

Ich bin mir nicht sicher, ob es funktioniert oder nicht, ich habe es nicht getestet.Auf jeden Fall ist es einen Versuch wert, oder?:) :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top