Appel Webapi non autorisé renvoyant la page de connexion au lieu de 401

180

Comment configurer mon projet mvc / webapi afin qu'une méthode webapi appelée à partir d'une vue rasoir ne renvoie pas la page de connexion lorsqu'elle n'est pas autorisée?

C'est une application MVC5 qui a également des contrôleurs WebApi pour les appels via javascript.

Les deux méthodes ci-dessous

[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
}

sont appelés via le code angulaire suivant:

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);
        });  
    }]
);

Je ne suis donc pas connecté et la première méthode renvoie les données avec succès. la deuxième méthode renvoie (dans la fonction de succès) des données qui contiennent l'équivalent d'une page de connexion. c'est-à-dire ce que vous obtiendriez dans mvc si vous demandiez une action de contrôleur qui était estampillée avec [Authorize] et que vous n'étiez pas connecté.

Je veux qu'il renvoie un 401 non autorisé, afin que je puisse afficher différentes données pour les utilisateurs en fonction de s'ils sont connectés ou non. Idéalement, si l'utilisateur est connecté, je veux pouvoir accéder à la propriété Utilisateur du contrôleur afin de pouvoir renvoyer des données spécifiques à ce membre.

MISE À JOUR: Étant donné qu'aucune des suggestions ci-dessous ne semble plus fonctionner (changements dans Identity ou WebAPI), ive a créé un exemple brut sur github qui devrait illustrer le problème.

Tim
la source

Réponses:

78

Il existe deux implémentations AuthorizeAttribute et vous devez vous assurer que vous faites référence à la bonne pour les API Web. Il y a System.Web.Http.AuthorizeAttribute qui est utilisé pour les API Web et System.Web.Mvc.AuthorizeAttribute qui est utilisé pour les contrôleurs avec vues. Http.AuthorizeAttribute renverra une erreur 401 si l'autorisation échoue et Mvc.AuthorizeAttribute redirigera vers la page de connexion.

Mis à jour le 26/11/2013

Il semble donc que les choses aient radicalement changé avec MVC 5, comme Brock Allen l'a souligné dans son article . Je suppose que le pipeline OWIN prend le relais et introduit un nouveau comportement. Désormais, lorsque l'utilisateur n'est pas autorisé, un statut de 200 est renvoyé avec les informations suivantes dans l'en-tête HTTP.

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

Vous pouvez modifier votre logique côté client pour vérifier ces informations dans l'en-tête afin de déterminer comment gérer cela, au lieu de rechercher un état 401 sur la branche d'erreur.

J'ai essayé de remplacer ce comportement dans un AuthorizeAttribute personnalisé en définissant le statut dans la réponse dans les méthodes OnAuthorization et HandleUnauthorizedRequest .

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

Mais cela n'a pas fonctionné. Le nouveau pipeline doit saisir cette réponse plus tard et la modifier en la même réponse que j'obtenais auparavant. Lancer une HttpException n'a pas non plus fonctionné car il est simplement changé en un état d'erreur 500.

J'ai testé la solution de Brock Allen et cela a fonctionné lorsque j'utilisais un appel jQuery ajax. Si cela ne fonctionne pas pour vous, je suppose que c'est parce que vous utilisez angular. Exécutez votre test avec Fiddler et voyez si ce qui suit est dans votre en-tête.

X-Requested-With: XMLHttpRequest

Si ce n'est pas le cas, c'est là le problème. Je ne suis pas familier avec angular mais si cela vous permet d'insérer vos propres valeurs d'en-tête, ajoutez-les à vos requêtes ajax et cela commencera probablement à fonctionner.

Kevin Junghans
la source
Je pense que j'utilise System.web.http.authorizeattribute, au moins ce webapicontroller n'a pas d'utilisation pour system.web.mvc, et aller à la définition de l'attribut autoriser m'envoie à system.web.http
Tim
Salut @ kevin-junghans complètement confus ici. l'exemple ci-dessus de shiva utilise un attribut d'autorisation mvc que je ne devrais sûrement pas appliquer à une action webapi, l'exemple de Brock allen ne semble pas fonctionner non plus, il ne pense pas que c'est une requête ajax quand je passe.
Tim du
1
je viens de repérer cette réponse (pensez que stackoverflow n'envoie pas de notifications) J'ai ajouté un exemple github pour illustrer le problème, et maintenant ajouté votre correctif aux en-têtes angulaires. Merci. Cela ne semble pas juste cependant qu'il n'y ait pas de propriété dans l'attribut authorize que je puisse vérifier ou que la fonctionnalité d'origine que vous avez mentionnée ne fonctionne plus.
Tim
3
Utilisation de POSTMAN et du paramètre d'en-tête X-Requested-With: XMLHttpRequest fonctionne pour moi ... merci
chemitaxis
Alors, que se passe-t-il si vous avez l'intention d'être un pur projet d'API Web? Je travaille sur un projet que quelqu'un d'autre a mis en place et que Authorize redirige comme décrit ici, mais j'ai un projet d'API différent qui fonctionne bien. Il doit y avoir quelque chose qui fait penser que c'est une application MVC plutôt qu'une application API, mais je ne trouve pas ce qui pourrait la gâcher.
Derek Greer
123

Brock Allen a un joli article de blog sur la façon de renvoyer 401 pour les appels ajax lors de l'utilisation de l'authentification Cookie et OWIN. http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/

Mettez ceci dans la méthode ConfigureAuth dans le fichier 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"));
}
Olav Nybø
la source
68
Une variante de ceci: si tous vos appels d'API Web passent par un certain chemin, par exemple /api, vous pouvez utiliser le chemin pour déterminer s'il faut rediriger. C'est particulièrement utile si vous avez des clients qui utilisent d'autres formats comme JSON. Remplacez l'appel à IsAjaxRequestpar if (!context.Request.Path.StartsWithSegments(new PathString("/api"))).
Edward Brey
En retard à la fête, mais cette méthode est la seule qui fonctionne pour moi, et semble être plus «précise».
Stephen Collins
Même tard (r) à la fête, mais cela s'est avéré très utile ... cela me stupéfie que le code généré par défaut le fasse si mal, d'une manière aussi frustrante et difficile à déboguer.
Nick
Si vous recherchez une solution WebApi, la réponse de Manik est une bonne alternative au commentaire hautement voté ici.
Dunc
5
En utilisant C # 6, voici une version plus petite de IsAjaxRequest: private static bool IsAjaxRequest(IOwinRequest request) { return request.Query?["X-Requested-With"] == "XMLHttpRequest" || request.Headers?["X-Requested-With"] == "XMLHttpRequest"; }
Peter Örneholm
85

Si vous ajoutez asp.net WebApi à l'intérieur du site Web asp.net MVC, vous voudrez probablement répondre sans autorisation à certaines demandes. Mais alors l'infrastructure ASP.NET entre en jeu et lorsque vous essayez de définir le code d'état de réponse sur HttpStatusCode.Unauthorized, vous obtenez une redirection 302 vers la page de connexion.

Si vous utilisez l'identité asp.net et l'authentification basée sur owin, voici un code qui peut vous aider à résoudre ce problème:

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);
}
Manik Arora
la source
1
J'ai changé le discriminant pour vérifier si les demandes acceptent text / html ou application / xhtml comme réponse, si elles ne le font pas, je suppose que c'est un client "automatisé" qui demande, une telle demande ajax
L.Trabacchin
4
Je préfère cette approche aussi. Le seul ajout que j'ai fait était de convertir LocalPath .ToLower () au cas où ils demanderaient "/ API" ou quelque chose.
FirstDivision
1
Merci beaucoup. Cela m'a sauvé la journée. :)
Amit Kumar
Quelqu'un at-il de la chance avec ça? CookieAuthenticationOptions n'a plus de propriété Provider à partir d'aspnet core 1.1.
Jeremy
27

J'ai eu la même situation lorsque OWIN redirige toujours la réponse 401 vers la page de connexion de WebApi.Notre API Web prend en charge non seulement les appels ajax d'Angular mais aussi les appels Mobile, Win Form. Par conséquent, la solution pour vérifier si la requête est une requête ajax n'est pas vraiment triée pour notre cas.

J'ai opté pour une autre approche consiste à injecter une nouvelle réponse d'en-tête: Suppress-Redirectsi les réponses proviennent de webApi. L'implémentation est sur le gestionnaire:

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);
    }
}

Et enregistrez ce gestionnaire au niveau global de WebApi:

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

Ainsi, au démarrage d'OWIN, vous pouvez vérifier si l'en-tête de réponse a 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;
}
cuongle
la source
Je vous remercie ! Nos API ont fonctionné sur toutes les plateformes, à l'exception de Xamarin / Android. Utilisera cette solution
Jurion
17

Dans les versions précédentes d'ASP.NET, vous deviez faire tout un tas de choses pour que cela fonctionne.

La bonne nouvelle est que vous utilisez ASP.NET 4.5. vous pouvez désactiver la redirection d'authentification par formulaire à l'aide de la nouvelle propriété HttpResponse.SuppressFormsAuthenticationRedirect .

Dans Global.asax:

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

EDIT : Vous voudrez peut-être également jeter un coup d'œil à cet article de Sergey Zwezdin qui présente une manière plus raffinée d'accomplir ce que vous essayez de faire.

Extraits de code pertinents et narration de l'auteur collés ci-dessous. Auteur original du code et de la narration - Sergey Zwezdin .

Tout d'abord, déterminons si la requête HTTP actuelle est une requête AJAX. Si oui, nous devrions désactiver le remplacement de HTTP 401 par 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);
    }
}

Deuxièmement - ajoutons une condition :: si l'utilisateur est authentifié, alors nous enverrons HTTP 403; et HTTP 401 sinon.

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);
    }
}

Bien joué. Nous devons maintenant remplacer toutes les utilisations de AuthorizeAttribute standard par ce nouveau filtre. Cela ne s'applique peut-être pas aux gars sime, qui est esthète du code. Mais je ne connais pas d'autre moyen. Si c'est le cas, passons aux commentaires, s'il vous plaît.

Le dernier, ce que nous devrions faire - ajouter la gestion HTTP 401/403 côté client. Nous pouvons utiliser ajaxError à jQuery pour éviter la duplication de code:

$(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.");
});

Le résultat -

  • Si l'utilisateur n'est pas authentifié, il sera alors redirigé vers une page de connexion après tout appel AJAX.
  • Si l'utilisateur est authentifié, mais ne dispose pas des autorisations suffisantes, il verra un message erorr convivial.
  • Si l'utilisateur est authentifié et dispose des autorisations suffisantes, il n'y a aucune erreur et la requête HTTP sera exécutée comme d'habitude.
Shiva
la source
Im j'utilise le nouveau cadre d'identité pour l'authentification via mvc. Ce paramètre n'empêcherait-il pas la connexion mvc de fonctionner ainsi que les appels Webapi?
Tim
5
quand j'ai vérifié cet exemple, il semble que l'attribut d'autorisation utilisé est la version MVC plutôt que la version WebApi. cependant, la version webapi n'a pas d'options pour supprimer l'authentification par formulaire.
Tim du
ma demande n'a pas de méthode IsAjaxRequest.
Tim
1
Tim regarde ceci pour IsAjaxRequest: brockallen.com/2013/10/27/ ... Si vous utilisez AngularJs sans éditer les en-têtes, vous n'aurez pas "XMLHttpRequest" et l'ajoutez ou vérifiez autre chose.
Tim
10

Si vous exécutez votre à Web APIpartir de votre MVCprojet, vous devrez créer une personnalisation AuthorizeAttributeà appliquer à vos APIméthodes. Dans le, IsAuthorized overridevous devez saisir le courant HttpContextpour empêcher la redirection, comme ceci:

    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);
    }
Serj Sagan
la source
8

En utilisant moi-même l'intégration d'Azure Active Directory, l'approche utilisant le CookieAuthenticationmiddleware n'a pas fonctionné pour moi. J'ai dû faire ce qui suit:

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

Si la requête provient du navigateur lui-même (et non d'un appel AJAX, par exemple), l'en-tête Accept contiendra la chaîne htmlquelque part. Ce n'est que lorsque le client accepte HTML que je considérerai une redirection comme quelque chose d'utile.

Mon application cliente peut gérer le 401 informant l'utilisateur que l'application n'a plus accès et doit se recharger pour se reconnecter.

Dave Van den Eynde
la source
Ceci est très similaire à la solution proposée pour une question connexe: stackoverflow.com/questions/34997674/...
Guillaume LaHaye
6

J'avais également une application MVC5 (System.Web) avec WebApi (en utilisant OWIN) et je voulais simplement empêcher que 401 réponses de WebApi soient modifiées en 302 réponses.

Ce qui a fonctionné pour moi a été de créer une version personnalisée de WebApi AuthorizeAttribute comme ceci:

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

Et de l'utiliser à la place du standard WebApi AuthorizeAttribute. J'ai utilisé le MVC AuthorizeAttribute standard pour garder le comportement MVC inchangé.

Jono Job
la source
Fonctionne, mais maintenant j'ai le problème que le client reçoit le statut -1 au lieu de 401
Sebastián Rojas
@ SebastiánRojas Je ne suis pas sûr de ce qui en serait la cause - définir le SuppressFormsAuthenticationRedirect drapeau l'a obligé à renvoyer simplement le 401 existant pour moi.
Jono Job
3

Installez simplement le package NeGet suivant

Package d'installation Microsoft.AspNet.WebApi.Owin

Écrivez le code suivant dans le fichier 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"));
    }
}

la source
Tout ce que j'avais à faire était d'ajouter ce filtre et il fonctionne config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));autrement User.Identity.IsAuthenticatedtoujoursfalse
Ricardo Saracino
1

si vous voulez attraper Content-Type == application / json, vous pouvez utiliser ce code:

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;

    }

Cordialement!!

chimitaxie
la source
1

J'avais du mal à obtenir à la fois le code d'état et une réponse textuelle fonctionnant dans les méthodes OnAuthorization / HandleUnauthorizedRequest. Cela s'est avéré être la meilleure solution pour moi:

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

Après avoir essayé d'éviter les redirections vers la page de connexion, j'ai réalisé que c'était en fait tout à fait approprié pour l'attribut Authorize. Il dit aller et obtenir l'autorisation. Au lieu des appels Api qui ne sont pas autorisés, je voulais juste ne révéler aucune information aux pirates informatiques. Cet objectif était plus facile à atteindre directement en ajoutant un nouvel attribut dérivé de Authorize qui masque à la place le contenu comme une erreur 404:

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

En mélangeant MVC et WebAPI, si la demande n'est pas autorisée, elle sera également redirigée vers la page de connexion, même dans la demande WebAPI. Pour cela, nous pouvons ajouter ci-dessous le code pour envoyer une réponse à l'application 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();
}
Programmeur avide
la source
0

Merci les gars!

Dans mon cas, j'ai combiné les réponses de cuongle et Shiva , et j'ai obtenu quelque chose comme ceci:

Dans le gestionnaire OnException () du contrôleur pour les exceptions d'API:

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

Dans le code de configuration de démarrage de l'application:

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);
                }
            }
        }
    });
Chakrit W
la source
-1

Dans MVC 5 avec Dot Net Framework 4.5.2, nous obtenons "application / json, texte de plainte .." sous l'en-tête "Accept" Ce sera agréable à utiliser comme suit:

isJson = headers["Content-Type"] == "application/json" || headers["Accept"].IndexOf("application/json", System.StringComparison.CurrentCultureIgnoreCase) >= 0;
Imran Javed
la source