Toujours un succès sur poste ajax avec HttpResponseMessage 401

Je reçois toujours statusCode=200 sur un poste ajax côté client, tandis que les serveurs HttpStatusCode.Unauthorized avec HttpStatusCode.Unauthorized .

Mon code de contrôleur:

 public class AccountApiController : ApiController { public HttpResponseMessage Login(HttpRequestMessage request, [FromBody]LoginViewModel loginModel) { return request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Unauthorized login."); } } 

Mon code ajax:

 $.ajax({ url: '/api/accountapi/login', type: 'POST', data: data }) .done(function (object, status, xhr) { alert("Success: " + xhr.status + " : " + xhr.statusText); }) .always(function (object) { $("#output").text(JSON.ssortingngify(object, null, 4)); }); 

Résultat: alerte avec texte Success: 200 : OK et fenêtre de sortie avec:

 { "Message": "Unauthorized login." } 

Donc, je peux obtenir un message d’erreur texte, mais je dois obtenir HttpStatusCode pour gérer les déclarations d’erreur. Aidez-moi, s’il vous plaît.

Plus d’informations sur ce problème et sur la solution élégante de Brock Allen: http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/

Il se peut que votre page redirige vers une page de connexion à l’aide du module d’authentification par formulaires dès que vous renvoyez HttpStatusCode.Unauthorized .

De MSDN:

Tous les utilisateurs non authentifiés se voient refuser l’access à toutes les pages de votre application. Si un utilisateur non authentifié tente d’accéder à une page, le module d’authentification par formulaires le redirige vers la page de connexion spécifiée par l’atsortingbut loginUrl de l’élément forms.

La page de connexion, ou la page vers laquelle elle est redirigée, reçoit alors le code de statut 200.

Comme un statut de 200 est renvoyé mais que l’utilisateur n’est pas autorisé, une autre option consiste à rechercher X-Responded-JSON avec un statut de 401 dans votre javascript.

 .done(function (object, status, xhr) { if (xhr.getResponseHeader("X-Responded-JSON") != null && JSON.parse(xhr.getResponseHeader("X-Responded-JSON")).status == "401") { //some message here return; } } 

Pour élaborer sur le commentaire de Valin et intégrer la solution de Brock Allen.

La réponse OK renvoyée intercepte la redirection vers un identifiant de formulaire:

 X-Responded-JSON : {"status": 401, "headers": {"location":"http:\/\/localhost:50004\/Login?ReturnUrl=%2FClient"}} 

Si vous souhaitez résoudre le problème sur le serveur, vous pouvez utiliser la solution de l’article de Brock Allen sur l’ utilisation d’un middleware d’authentification de cookie avec l’API Web et les codes de réponse 401 au lieu de rechercher la réponse à cette erreur interne

Normalement, lorsque vous utilisez un middleware d’authentification par cookie, lorsque le serveur (MVC ou WebForms) émet un code 401, la réponse est convertie en une redirection 302 vers la page de connexion (comme configuré par LoginPath sur CookieAuthenticationOptions ). Mais lorsqu’un appel Ajax est effectué et que la réponse est un message 401, il serait inutile de renvoyer une redirection 302 vers la page de connexion. Au lieu de cela, vous vous attendez à ce que la réponse 401 soit renvoyée. Malheureusement, ce n’est pas le comportement que nous avons avec le middleware de cookie – la réponse est modifiée en un code d’état 200 avec un corps de réponse JSON avec un message:

 {"Message":"Authorization has been denied for this request."} 

Je ne suis pas sûr de la nécessité de cette fonctionnalité. Pour le modifier, vous devez prendre le contrôle du comportement en cas de réponse non autorisée 401 en configurant CookieAuthenticationProvider sur le middleware d’authentification de cookie:

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

Notez qu’il gère l’événement OnApplyRedirect. Lorsque l’appel n’est pas un appel Ajax, nous le redirigeons. Sinon, nous ne faisons rien qui permet au 401 d’être renvoyé à l’appelant.

Le chèque de IsAjaxRequest est simplement copié à partir d’une aide dans le projet katana:

 private static bool IsAjaxRequest(IOwinRequest request) { IReadableSsortingngCollection 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")); }