Ignorare il reindirizzamento automatico dell'autenticazione dei moduli all'accesso, come fare?

StackOverflow https://stackoverflow.com/questions/35322

Domanda

Sto scrivendo un'app utilizzando asp.net-mvc distribuendola su iis6.Sto utilizzando l'autenticazione basata su moduli.Di solito, quando un utente tenta di accedere a una risorsa senza la corretta autorizzazione, desidero che venga reindirizzato a una pagina di accesso.FormsAuth lo fa per me abbastanza facilmente.

Problema:Ora ho un'azione a cui si accede da un'app console.Qual è il modo più rapido per far sì che questa azione risponda con lo stato 401 invece di reindirizzare la richiesta alla pagina di accesso?

Voglio che l'app della console sia in grado di reagire a questo StatusCode 401 invece che sia trasparente.Vorrei anche mantenere l'impostazione predefinita, reindirizzare le richieste non autorizzate al comportamento della pagina di accesso.

Nota:Come test ho aggiunto questo al mio global.asax e non ha ignorato l'autenticazione dei moduli:

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

@Dale e Andy

Sto utilizzando AuthorizeAttributeFilter fornito nell'anteprima 4 di MVC.Questo restituisce un HttpUnauthorizedResult.Questo risultato imposta correttamente statusCode su 401.Il problema, a quanto ho capito, è che asp.net intercetta la risposta (poiché è contrassegnata come 401) e la reindirizza alla pagina di accesso invece di lasciarla passare.Voglio ignorare questa intercettazione per determinati URL.

È stato utile?

Soluzione

Ok, ho lavorato su questo.Ho creato un ActionResult personalizzato (HttpForbiddenResult) e un ActionFilter personalizzato (NoFallBackAuthorize).

Per evitare il reindirizzamento, HttpForbiddenResult contrassegna le risposte con il codice di stato 403.FormsAuthentication non rileva le risposte con questo codice, quindi il reindirizzamento dell'accesso viene effettivamente ignorato.Il filtro NoFallBackAuthorize verifica se l'utente è autorizzato in modo molto simile al filtro Autorizza incluso.Differisce in quanto restituisce HttpForbiddenResult quando l'accesso viene negato.

Il HttpForbiddenResult è piuttosto banale:

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

Non sembra essere possibile ignorare il reindirizzamento della pagina di accesso in FormsAuthenticationModule.

Altri suggerimenti

Potrebbe essere un errore (e potrebbe anche non funzionare), ma nella tua pagina di accesso controlla se Request.QueryString["ReturnUrl"] != null e se è così impostato Response.StatusCode = 401.

Tieni presente che dovrai comunque autenticare l'app della console in qualche modo.Non ottieni l'autenticazione di base HTTP gratuitamente:devi crearne uno tuo, ma ci sono molte implementazioni a riguardo.

Hai scritto il tuo attributo FormsAuth per l'azione?In tal caso, nel metodo OnActionExecuting, ti viene passato il FilterExecutingContext.Puoi usarlo per restituire il codice 401.

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

Questo dovrebbe funzionare.Non sono sicuro se hai scritto l'attributo FormsAuth o se l'hai ottenuto da qualche altra parte.

Non ho ancora utilizzato AuthorizeAttribute disponibile nell'anteprima 4.Ne ho creato uno mio, perché utilizzo il framework MVC sin dal primo CTP.Ho dato una rapida occhiata all'attributo in reflector e internamente sta facendo ciò che ho menzionato sopra, tranne che usano l'equivalente esadecimale di 401.Dovrò esaminare più a fondo la chiamata, per vedere dove viene catturata l'eccezione, perché molto probabilmente è lì che stanno eseguendo il reindirizzamento.Questa è la funzionalità che dovrai sovrascrivere.Non sono sicuro che tu possa ancora farlo, ma ti risponderò quando lo troverò e ti darò una soluzione, a meno che Haacked non lo veda e lo pubblichi lui stesso.

Ho fatto qualche ricerca su Google e questo è quello che mi è venuto in mente:


    HttpContext.Current.Response.StatusCode = 401;

Non sono sicuro che funzioni o meno, non l'ho testato.In ogni caso, vale la pena provare, giusto?:)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top