Chiamata webapi non autorizzata che restituisce la pagina di accesso anziché 401


180

Come configuro il mio progetto mvc / webapi in modo che un metodo webapi chiamato da una vista rasoio non ritorni la pagina di accesso quando non è autorizzato?

È un'applicazione MVC5 che ha anche controller WebApi per le chiamate tramite JavaScript.

I due metodi seguenti

[Route("api/home/LatestProblems")]      
[HttpGet()]
public List<vmLatestProblems> LatestProblems()
{
    // Something here
}

[Route("api/home/myLatestProblems")]
[HttpGet()]
[Authorize(Roles = "Member")]
public List<vmLatestProblems> mylatestproblems()
{
   // Something there
}

sono chiamati tramite il seguente codice angolare:

angular.module('appWorship').controller('latest', 
    ['$scope', '$http', function ($scope,$http) {         
        var urlBase = baseurl + '/api/home/LatestProblems';
        $http.get(urlBase).success(function (data) {
            $scope.data = data;
        }).error(function (data) {
            console.log(data);
        });
        $http.get(baseurl + '/api/home/mylatestproblems')
          .success(function (data) {
            $scope.data2 = data;
        }).error(function (data) {
            console.log(data);
        });  
    }]
);

Quindi non ho effettuato l'accesso e il primo metodo restituisce correttamente i dati. il secondo metodo restituisce (nella funzione Success) dati che contengono l'equivalente di una pagina di accesso. ad es. cosa otterresti in mvc se richiedessi un'azione del controller contrassegnata con [Autorizza] e non hai effettuato l'accesso.

Voglio che restituisca un 401 non autorizzato, in modo da poter visualizzare dati diversi per gli utenti in base al fatto che abbiano effettuato l'accesso o meno. Idealmente, se l'utente ha effettuato l'accesso, desidero poter accedere alla proprietà Utente del controllore in modo da poter restituire dati specifici per quel membro.

AGGIORNAMENTO: Dal momento che nessuno dei seguenti suggerimenti sembra funzionare più (modifiche a Identity o WebAPI), ho creato un esempio grezzo su github che dovrebbe illustrare il problema.

Risposte:


78

Esistono due implementazioni di AuthorizeAttribute e devi assicurarti di fare riferimento a quella corretta per le API Web. C'è System.Web.Http.AuthorizeAttribute che viene utilizzato per le API Web e System.Web.Mvc.AuthorizeAttribute che viene utilizzato per i controller con viste. Http.AuthorizeAttribute restituirà un errore 401 se l'autorizzazione non riesce e Mvc.AuthorizeAttribute reindirizzerà alla pagina di accesso.

Aggiornato il 26/11/2013

Quindi sembra che le cose siano cambiate drasticamente con MVC 5 come ha sottolineato Brock Allen nel suo articolo . Immagino che la pipeline OWIN prenda il sopravvento e introduca alcuni nuovi comportamenti. Ora, quando l'utente non è autorizzato, viene restituito uno stato di 200 con le seguenti informazioni nell'intestazione HTTP.

X-Responded-JSON: {"status":401,"headers":{"location":"http:\/\/localhost:59540\/Account\/Login?ReturnUrl=%2Fapi%2FTestBasic"}}

È possibile modificare la logica sul lato client per controllare queste informazioni nell'intestazione per determinare come gestirle, anziché cercare uno stato 401 sul ramo di errore.

Ho provato a ignorare questo comportamento in un AuthorizeAttribute personalizzato impostando lo stato nella risposta nei metodi OnAuthorization e HandleUnauthorizedRequest .

actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);

Ma questo non ha funzionato. La nuova pipeline deve acquisire questa risposta in un secondo momento e modificarla nella stessa risposta che stavo ricevendo in precedenza. Anche il lancio di una HttpException non ha funzionato in quanto è appena cambiato in uno stato di errore 500.

Ho testato la soluzione di Brock Allen e ha funzionato quando stavo usando una chiamata ajax jQuery. Se non funziona per te la mia ipotesi è che è perché stai usando angolare. Esegui il test con Fiddler e verifica se quanto segue è nell'intestazione.

X-Requested-With: XMLHttpRequest

In caso contrario, questo è il problema. Non ho familiarità con angolare, ma se ti consente di inserire i tuoi valori di intestazione, aggiungi questo alle tue richieste Ajax e probabilmente inizierà a funzionare.


penso che sto usando System.web.http.authorizeattribute, almeno questo webapicontroller non ha un utilizzo per system.web.mvc, e andando alla definizione dell'attributo autorizza mi manda a system.web.http
Tim

Ciao @ kevin-junghans completamente confuso qui. l'esempio sopra di shiva usa un attributo di autorizzazione mvc che sicuramente non dovrei applicare a un'azione webapi, L'esempio di Brock Allen non sembra funzionare o non pensa che sia una richiesta Ajax quando passo attraverso.
Tim

1
ho appena individuato questa risposta (pensa che stackoverflow non invii notifiche) Ho aggiunto un esempio github per illustrare il problema e ora ho aggiunto la tua correzione alle intestazioni angolari. Grazie. Non sembra giusto, tuttavia, che non ci sia una proprietà nell'attributo autorizzabile che posso controllare o che la funzionalità originale menzionata non funzioni più.
Tim

3
Utilizzo di POSTMAN e dell'intestazione param X-Requested-With: XMLHttpRequest funziona per me ... grazie
chemitaxis,

Quindi, cosa succede se hai quello che intendi essere un progetto API Web puro che fa questo? Sto lavorando a un progetto che qualcun altro ha impostato e l'autorizzazione sta reindirizzando come descritto qui, ma ho un diverso progetto API che funziona bene. Deve esserci qualcosa che lo fa pensare che sia un'app MVC piuttosto che un'app per le API, ma non riesco a trovare cosa potrebbe esserlo.
Derek Greer,

123

Brock Allen ha un bel post sul blog su come restituire 401 per chiamate ajax quando si utilizza l'autenticazione con cookie e OWIN. http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/

Inseriscilo nel metodo ConfigureAuth nel file Startup.Auth.cs:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
  AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
  LoginPath = new PathString("/Account/Login"),
  Provider = new CookieAuthenticationProvider
  {
    OnApplyRedirect = ctx =>
    {
      if (!IsAjaxRequest(ctx.Request))
      {
        ctx.Response.Redirect(ctx.RedirectUri);
      }
    }
  }
});

private static bool IsAjaxRequest(IOwinRequest request)
{
  IReadableStringCollection query = request.Query;
  if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest"))
  {
     return true;
  }
  IHeaderDictionary headers = request.Headers;
  return ((headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest"));
}

68
Una variazione su questo: se tutte le chiamate dell'API Web seguono un determinato percorso, ad esempio /api, è possibile utilizzare il percorso per determinare se reindirizzare. È particolarmente utile se si dispone di client che utilizzano altri formati come JSON. Sostituisci la chiamata IsAjaxRequestcon if (!context.Request.Path.StartsWithSegments(new PathString("/api"))).
Edward Brey,

In ritardo alla festa, ma questo metodo è l'unico che mi preoccupa e sembra essere più "accurato".
Stephen Collins,

Anche in ritardo (r) alla festa, ma questo si è rivelato molto utile ... mi fa impazzire che il codice generato di default lo faccia in modo così sbagliato, in un modo così frustrantemente difficile da eseguire il debug.
Nick,

Se stai cercando una soluzione WebApi, la risposta di Manik è una buona alternativa al commento molto apprezzato qui.
Dunc,

5
Usando C # 6, ecco una versione più piccola di IsAjaxRequest: private static bool IsAjaxRequest(IOwinRequest request) { return request.Query?["X-Requested-With"] == "XMLHttpRequest" || request.Headers?["X-Requested-With"] == "XMLHttpRequest"; }
Peter Örneholm,

85

Se si aggiunge asp.net WebApi all'interno del sito Web asp.net MVC, probabilmente si desidera rispondere non autorizzato ad alcune richieste. Ma poi entra in gioco l'infrastruttura ASP.NET e quando provi a impostare il codice di stato della risposta su HttpStatusCode.Unauthorized otterrai 302 reindirizzamenti alla pagina di accesso.

Se stai usando l'identità asp.net e l'autenticazione basata su owin qui un codice che può aiutarti a risolvere quel problema:

public void ConfigureAuth(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider()
        {
            OnApplyRedirect = ctx =>
            {
                if (!IsApiRequest(ctx.Request))
                {
                    ctx.Response.Redirect(ctx.RedirectUri);
                }
            }
        }
    });

    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}


private static bool IsApiRequest(IOwinRequest request)
{
    string apiPath = VirtualPathUtility.ToAbsolute("~/api/");
    return request.Uri.LocalPath.StartsWith(apiPath);
}

1
ho modificato il discriminante per verificare se le richieste accettano text / html o application / xhtml come risposta, in caso contrario suppongo sia un client "automatizzato" che richiede, tale richiesta ajax
L.Trabacchin

4
Preferisco anche questo approccio. L'unica aggiunta che ho fatto è stata la conversione di LocalPath .ToLower () nel caso in cui richiedessero "/ API" o qualcosa del genere.
FirstDivision

1
Molte grazie. Mi ha salvato la giornata. :)
Amit Kumar,

Qualcuno ha fortuna con questo? CookieAuthenticationOptions non ha più una proprietà Provider a partire da aspnet core 1.1.
Jeremy,

27

Ho avuto la stessa situazione quando OWIN reindirizza sempre la risposta 401 alla pagina di accesso da WebApi. La nostra API Web supporta non solo le chiamate Ajax da Angular ma anche Mobile, Win Form. Pertanto, la soluzione per verificare se la richiesta è ajax non è realmente ordinata per il nostro caso.

Ho optato per un altro approccio è quello di iniettare una nuova risposta nell'intestazione: Suppress-Redirectse le risposte provengono da webApi. L'implementazione è sul gestore:

public class SuppressRedirectHandler : DelegatingHandler
{
    /// <summary>
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return base.SendAsync(request, cancellationToken).ContinueWith(task =>
        {
            var response = task.Result;
            response.Headers.Add("Suppress-Redirect", "True");
            return response;
        }, cancellationToken);
    }
}

E registra questo gestore a livello globale di WebApi:

config.MessageHandlers.Add(new SuppressRedirectHandler());

Quindi, all'avvio di OWIN puoi verificare se l'intestazione della risposta ha Suppress-Redirect:

public void Configuration(IAppBuilder app)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationMode = AuthenticationMode.Active,
        AuthenticationType = DefaultApplicationTypes.ApplicationCookie,
        ExpireTimeSpan = TimeSpan.FromMinutes(48),

        LoginPath = new PathString("/NewAccount/LogOn"),

        Provider = new CookieAuthenticationProvider()
        {
            OnApplyRedirect = ctx =>
            {
                var response = ctx.Response;
                if (!IsApiResponse(ctx.Response))
                {
                    response.Redirect(ctx.RedirectUri);
                }
            }
        }
    });
}

private static bool IsApiResponse(IOwinResponse response)
{
    var responseHeader = response.Headers;

    if (responseHeader == null) 
        return false;

    if (!responseHeader.ContainsKey("Suppress-Redirect"))
        return false;

    if (!bool.TryParse(responseHeader["Suppress-Redirect"], out bool suppressRedirect))
        return false;

    return suppressRedirect;
}

Grazie ! Le nostre API hanno funzionato su ogni piastra, ad eccezione di Xamarin / Android. Utilizzerà questa soluzione
Jurion

17

Nelle versioni precedenti di ASP.NET, dovevi fare un sacco di cose per farlo funzionare.

La buona notizia è che dal momento che stai utilizzando ASP.NET 4.5. è possibile disabilitare il reindirizzamento dell'autenticazione tramite i moduli HttpResponse.SuppressFormsAuthenticationRedirect proprietà .

In Global.asax:

protected void Application_EndRequest(Object sender, EventArgs e)
{
        HttpApplication context = (HttpApplication)sender;
        context.Response.SuppressFormsAuthenticationRedirect = true;
}

EDIT : potresti anche dare un'occhiata a questo articolo di Sergey Zwezdin che ha un modo più raffinato di realizzare ciò che stai cercando di fare.

Rilevanti frammenti di codice e narrazione dell'autore incollati di seguito. Autore originale di codice e narrazione - Sergey Zwezdin .

Innanzitutto, determiniamo se la richiesta HTTP corrente è una richiesta AJAX. Se sì, dovremmo disabilitare la sostituzione di HTTP 401 con HTTP 302:

public class ApplicationAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        var httpContext = filterContext.HttpContext;
        var request = httpContext.Request;
        var response = httpContext.Response;

        if (request.IsAjaxRequest())
            response.SuppressFormsAuthenticationRedirect = true;

        base.HandleUnauthorizedRequest(filterContext);
    }
}

Secondo: aggiungiamo una condizione :: se l'utente è autenticato, invieremo HTTP 403; e HTTP 401 altrimenti.

public class ApplicationAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        var httpContext = filterContext.HttpContext;
        var request = httpContext.Request;
        var response = httpContext.Response;
        var user = httpContext.User;

        if (request.IsAjaxRequest())
        {
            if (user.Identity.IsAuthenticated == false)
                response.StatusCode = (int)HttpStatusCode.Unauthorized;
            else
                response.StatusCode = (int)HttpStatusCode.Forbidden;

            response.SuppressFormsAuthenticationRedirect = true;
            response.End();
        }

        base.HandleUnauthorizedRequest(filterContext);
    }
}

Molto bene. Ora dovremmo sostituire tutti gli utilizzi di AuthorizeAttribute standard con questo nuovo filtro. Potrebbe non essere applicabile a ragazzi semplici, che sono esteti del codice. Ma non conosco nessun altro modo. Se hai, andiamo ai commenti, per favore.

L'ultimo, cosa dovremmo fare: aggiungere la gestione HTTP 401/403 sul lato client. Possiamo usare ajaxError su jQuery per evitare la duplicazione del codice:

$(document).ajaxError(function (e, xhr) {
    if (xhr.status == 401)
        window.location = "/Account/Login";
    else if (xhr.status == 403)
        alert("You have no enough permissions to request this resource.");
});

Il risultato -

  • Se l'utente non è autenticato, verrà reindirizzato a una pagina di accesso dopo ogni chiamata AJAX.
  • Se l'utente è autenticato, ma non dispone di autorizzazioni sufficienti, vedrà un messaggio erorr intuitivo.
  • Se l'utente è autenticato e dispone di autorizzazioni sufficienti, non ci sono errori e la richiesta HTTP verrà eseguita normalmente.

Sto usando il nuovo framework di identità per auth via mvc. Questa impostazione non impedirebbe il funzionamento di login mvc così come le chiamate webapi?
Tim

5
quando ho controllato questo esempio, sembra che l'attributo autorizzato utilizzato sia la versione MVC piuttosto che la versione WebApi. tuttavia la versione di webapi non ha opzioni per la soppressione dell'autenticazione dei moduli.
Tim

la mia richiesta non ha un metodo IsAjaxRequest.
Tim

1
Tim guarda questo per IsAjaxRequest: brockallen.com/2013/10/27/… Se stai usando AngularJs senza modificare le intestazioni non avrai "XMLHttpRequest" e aggiungilo o controlla qualcos'altro.
Tim

10

Se stai eseguendo il tuo Web APIall'interno del tuo MVCprogetto, dovrai creare un metodo personalizzato AuthorizeAttributeda applicare ai tuoi APImetodi. All'interno del IsAuthorized overridedevi prendere la corrente HttpContextper evitare il reindirizzamento, in questo modo:

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        if (string.IsNullOrWhiteSpace(Thread.CurrentPrincipal.Identity.Name))
        {
            var response = HttpContext.Current.Response;
            response.SuppressFormsAuthenticationRedirect = true;
            response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden;
            response.End();
        }

        return base.IsAuthorized(actionContext);
    }

8

Usando me stesso l'integrazione di Azure Active Directory, l'approccio con il CookieAuthenticationmiddleware non ha funzionato per me. Ho dovuto fare quanto segue:

app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions
    {
        ...
        Notifications = new OpenIdConnectAuthenticationNotifications
        {   
            ...         
            RedirectToIdentityProvider = async context =>
            {
                if (!context.Request.Accept.Contains("html"))
                {
                    context.HandleResponse();
                }
            },
            ...
        }
    });

Se la richiesta proviene dal browser stesso (e non da una chiamata AJAX, ad esempio), l'intestazione Accept conterrà la stringa html in esso da qualche parte. Solo quando il client accetta l'HTML considererò un reindirizzamento qualcosa di utile.

La mia applicazione client è in grado di gestire il 401 informando l'utente che l'app non ha più accesso e deve ricaricare per accedere nuovamente.


Questo è molto simile alla soluzione proposta per una domanda correlata: stackoverflow.com/questions/34997674/…
Guillaume LaHaye

6

Avevo anche un'applicazione MVC5 (System.Web) con WebApi (utilizzando OWIN) e volevo solo impedire che 401 risposte da WebApi venissero cambiate in 302 risposte.

Ciò che ha funzionato per me è stato creare una versione personalizzata di WebApi AuthorizeAttribute in questo modo:

public class MyAuthorizeAttribute : System.Web.Http.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        base.HandleUnauthorizedRequest(actionContext);
        HttpContext.Current.Response.SuppressFormsAuthenticationRedirect = true;
    }
}

E usarlo al posto del WebApi AuthorizeAttribute standard. Ho usato lo standard MVC AuthorizeAttribute per mantenere invariato il comportamento MVC.


Funziona, ma ora ho il problema che il client riceve lo stato -1 invece di 401
Sebastián Rojas

@ SebastiánRojas Non sono sicuro di cosa potrebbe causare questo - l'impostazione della SuppressFormsAuthenticationRedirect bandiera ha causato la restituzione dei 401 esistenti per me.
Jono Job

3

Basta installare il seguente pacchetto NeGet

Pacchetto di installazione Microsoft.AspNet.WebApi.Owin

Scrivi il seguente codice nel file WebApiConfig.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        //Web API configuration and services
        //Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
    }
}

Tutto quello che dovevo fare era aggiungere questo filtro e il suo funzionamento config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));altrimenti User.Identity.IsAuthenticatedè semprefalse
Ricardo Saracino il

1

se vuoi catturare Content-Type == application / json puoi usare quel codice:

private static bool IsAjaxRequest(IOwinRequest request)
    {
        IReadableStringCollection queryXML = request.Query;
        if ((queryXML != null) && (queryXML["X-Requested-With"] == "XMLHttpRequest"))
        {
            return true;
        }

        IReadableStringCollection queryJSON = request.Query;
        if ((queryJSON != null) && (queryJSON["Content-Type"] == "application/json"))
        {
            return true;
        }

        IHeaderDictionary headersXML = request.Headers;
        var isAjax = ((headersXML != null) && (headersXML["X-Requested-With"] == "XMLHttpRequest"));

        IHeaderDictionary headers = request.Headers;
        var isJson = ((headers != null) && (headers["Content-Type"] == "application/json"));

        return isAjax || isJson;

    }

Saluti!!


1

Ho avuto difficoltà a ottenere sia il codice di stato che una risposta testuale che funzionavano nei metodi OnAuthorization / HandleUnauthorizedRequest. Questa si è rivelata la soluzione migliore per me:

    actionContext.Response = new HttpResponseMessage()
    {
        StatusCode = HttpStatusCode.Forbidden,
        Content = new StringContent(unauthorizedMessage)
    };

1

Dopo molte storie che cercavano di evitare i reindirizzamenti alla pagina di accesso, mi sono reso conto che questo è in realtà abbastanza appropriato per l'attributo Autorizza. Sta dicendo andare a ottenere l'autorizzazione. Invece per le chiamate Api che non sono autorizzate, volevo solo non rivelare alcuna informazione a chi fosse un hacker. Questo obiettivo era più facile da raggiungere direttamente aggiungendo un nuovo attributo derivato da Autorizza che invece nasconde il contenuto come errore 404:

public class HideFromAnonymousUsersAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
         actionContext.Response = ActionContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, "Access Restricted");
    }
}

1

Mescolando MVC e WebAPI, se la richiesta non è autorizzata, reindirizzerà alla pagina di accesso anche nella richiesta WebAPI. Per questo, possiamo aggiungere il codice seguente per inviare una risposta all'applicazione mobile

protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
    var httpContext = HttpContext.Current;
    if (httpContext == null)
    {
        base.HandleUnauthorizedRequest(actionContext);
        return;
    }

    actionContext.Response = httpContext.User.Identity.IsAuthenticated == false ?
        actionContext.Request.CreateErrorResponse(
      System.Net.HttpStatusCode.Unauthorized, "Unauthorized") :
       actionContext.Request.CreateErrorResponse(
      System.Net.HttpStatusCode.Forbidden, "Forbidden");

    httpContext.Response.SuppressFormsAuthenticationRedirect = true;
    httpContext.Response.End();
}

0

Grazie ragazzi!

Nel mio caso, ho combinato le risposte di Cuongle e Shiva e ho ottenuto qualcosa del genere:

Nel gestore OnException () del controller per le eccezioni API:

filterContext.ExceptionHandled = true;
//...
var response = filterContext.HttpContext.Response;
response.Headers.Add("Suppress-Redirect", "true");
response.SuppressFormsAuthenticationRedirect = true;

Nel codice di configurazione dell'avvio dell'app:

app.UseCookieAuthentication(new CookieAuthenticationOptions {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider {
            OnValidateIdentity = ctx => {
                return validateFn.Invoke(ctx);
            },
            OnApplyRedirect = ctx =>
            {
                bool enableRedir = true;
                if (ctx.Response != null)
                {
                    string respType = ctx.Response.ContentType;
                    string suppress = ctx.Response.Headers["Suppress-Redirect"];
                    if (respType != null)
                    {
                        Regex rx = new Regex("^application\\/json(;(.*))?$",
                            RegexOptions.IgnoreCase);
                        if (rx.IsMatch(respType))
                        {
                            enableRedir = false;
                        }  
                    }
                    if ((!String.IsNullOrEmpty(suppress)) && (Boolean.Parse(suppress)))
                    {
                        enableRedir = false;
                    }
                }
                if (enableRedir)
                {
                    ctx.Response.Redirect(ctx.RedirectUri);
                }
            }
        }
    });

-1

In MVC 5 con Dot Net Framework 4.5.2 stiamo ottenendo "application / json, plaint text .." sotto l'intestazione "Accept" Sarà piacevole usare come segue:

isJson = headers["Content-Type"] == "application/json" || headers["Accept"].IndexOf("application/json", System.StringComparison.CurrentCultureIgnoreCase) >= 0;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.