5 Stimmen

Mehr Kontrolle über ASP.Net MVC's Authorize; um AJAX-Anfragen AJAXy zu halten

Ich habe einige Aktionsmethoden hinter einer Autorisierung wie:

[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Create(int siteId, Comment comment) {

Das Problem, das ich habe, ist, dass ich eine Anfrage über AJAX an Comment/Create mit

X-Requested-With=XMLHttpRequest

was dazu beiträgt, die Anfrage als AJAX zu identifizieren. Wenn der Benutzer nicht eingeloggt ist und auf die Authorize-Wand trifft, wird er umgeleitet zu

/Account/LogOn?ReturnUrl=Comment%2fCreate

was den AJAX-Workflow unterbricht. Ich muss umgeleitet werden zu

/Account/LogOn?X-Requested-With=XMLHttpRequest

Haben Sie eine Idee, wie das erreicht werden kann? Gibt es Möglichkeiten, mehr Kontrolle darüber zu erhalten, was passiert, wenn eine Autorisierung angefordert wird?

5voto

pupeno Punkte 265290

Dank Lewis Kommentare war ich in der Lage, diese Lösung zu erreichen (die bei weitem nicht perfekt ist, mit meinen eigenen Kommentaren gepostet, wenn Sie die Korrekturen fühlen sich frei zu bearbeiten und entfernen Sie diesen Satz), aber es funktioniert:

public class AjaxAuthorizeAttribute : AuthorizeAttribute {
    override public void OnAuthorization(AuthorizationContext filterContext) {
        base.OnAuthorization(filterContext);
        // Only do something if we are about to give a HttpUnauthorizedResult and we are in AJAX mode.
        if (filterContext.Result is HttpUnauthorizedResult && filterContext.HttpContext.Request.IsAjaxRequest()) {
            // TODO: fix the URL building:
            // 1- Use some class to build URLs just in case LoginUrl actually has some query already.
            // 2- When leaving Result as a HttpUnauthorizedResult, ASP.Net actually does some nice automatic stuff, like adding a ReturnURL, when hardcodding the URL here, that is lost.
            String url = System.Web.Security.FormsAuthentication.LoginUrl + "?X-Requested-With=XMLHttpRequest";
            filterContext.Result = new RedirectResult(url);
        }
    }
}

3voto

SlimShaggy Punkte 2709

Kürzlich bin ich auf genau dasselbe Problem gestoßen und habe den von J. Pablo Fernández veröffentlichten Code verwendet mit einer Änderung zur Berücksichtigung von Rückgabe-URLs. Hier ist er:

public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    override public void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
        // Only do something if we are about to give a HttpUnauthorizedResult and we are in AJAX mode. 
        if (filterContext.Result is HttpUnauthorizedResult && filterContext.HttpContext.Request.IsAjaxRequest())
        {
            // TODO: fix the URL building: 
            // 1- Use some class to build URLs just in case LoginUrl actually has some query already. 
            HttpRequestBase request = filterContext.HttpContext.Request;
            string returnUrl = request.Path;
            bool queryStringPresent = request.QueryString.Count > 0;
            if (queryStringPresent || request.Form.Count > 0)
                returnUrl += '?' + request.QueryString.ToString();
            if (queryStringPresent)
                returnUrl += '&';
            returnUrl += request.Form;
            String url = System.Web.Security.FormsAuthentication.LoginUrl +
                         "?X-Requested-With=XMLHttpRequest&ReturnUrl=" +
                         HttpUtility.UrlEncode(returnUrl);
            filterContext.Result = new RedirectResult(url);
        }
    }
}

1voto

Jarrett Meyer Punkte 18916

Statt das authorize-Attribut zu verwenden, habe ich etwas wie das Folgende gemacht.

public ActionResult SomeCall(string someData)
{
    if (Request.IsAjaxRequest() == false)
    {
        // TODO: do the intended thing.
    }
    else
    {
        // This should only work with AJAX requests, so redirect
        // the user to an appropriate location.
        return RedirectToAction("Action", "Controller", new { id = ?? });
    }
}

0voto

Lewis Punkte 5709

Ich denke, der richtige Weg, um dies zu behandeln wäre in Ihrem Javascript machen die AJAX-Aufruf sein.

Wenn der Benutzer autorisiert (oder authentifiziert, wie Ihr Code andeutet) sein muss und dies nicht der Fall ist, sollten Sie ihn darüber informieren und ihm vielleicht gar nicht erst erlauben, einen Kommentar abzugeben.

Wenn das jedoch nicht Ihren Bedürfnissen entspricht. Sie könnten versuchen, Ihren eigenen Authorize Action-Filter zu schreiben, vielleicht in Anlehnung an den, der mit dem MVC-Framework geliefert wird, aber nach Ihren Wünschen umleitet. Das ist ziemlich einfach.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X