net mvc ihttpactionresult example error code asp c# asp.net asp.net-mvc http-status-codes asp.net-mvc-5

c# - mvc - HttpStatusCodeResult(401) devuelve "200 OK"



return http error c# (5)

Utilizando ASP.NET MVC 5, me gustaría devolver el código de estado HTTP apropiado para diferentes escenarios (401 para el usuario no está autenticado, 403 cuando el usuario no tiene derecho a algún recurso, etc.), y luego manejarlos en jQuery.

Pero el problema es que cuando intento devolver 401, siempre devuelve "200: OK". MVC 5 RC1 estaba dando "302: Encontrado" en lugar de 401, por lo que podría usar una solución alternativa ( HttpStatusCodeResult (401) devuelve "302 Encontrado" ). Pero ahora pasé de MVC 5 RC1 a MVC 5 y este comportamiento cambió. Ahora siempre es "200: OK". Entonces mi solución no sirve para nada, por supuesto que no puedo reemplazar 200 con nada más.

public ActionResult My() { if (User.Identity.IsAuthenticated == false) { return new HttpStatusCodeResult(401, "User is not authenticated."); // Returns "200: OK" } // ... other code ... }

¿Cómo resolver esto?


En Statup.cs tuve que configurar AutomaticChallenge en false . Una vez que lo hice, dejó de hacer el redireccionamiento de URL (que dio como resultado el estado 200) y me dio el estado 401 que deseaba.

public void ConfigureServices(IServiceCollection services) { services.AddIdentity<ApplicationUser, ApplicationRole>(options => { options.Cookies.ApplicationCookie.AutomaticChallenge = false; //<@@@@@@@ //... }) .AddEntityFrameworkStores<ApplicationDbContext, int>() .AddDefaultTokenProviders(); }

Si ha configurado algún middleware de cookies:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IAntiforgery antiforgery) { app.UseCookieAuthentication(new CookieAuthenticationOptions() { AuthenticationScheme = "__auth__", LoginPath = "/account/login", AccessDeniedPath = "/account/forbidden", AutomaticAuthenticate = true, AutomaticChallenge = false //<@@@@@@@ }); }


La solución al problema se puede encontrar en http://kevin-junghans.blogspot.in/2013/12/returning-401-http-status-code-on.html

Debes modificar tu clase de Startup esta manera:

public partial class Startup { 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")); } // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 public void ConfigureAuth(IAppBuilder app) { // Enable the application to use a cookie to store information for the signed in user 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); } } } }); // Use a cookie to temporarily store information about a user logging in with a third party login provider app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); }

}


La tubería MVC 5+ modifica los códigos de respuesta 401.

Opción 1 con .net 4.5

puede establecer HttpContext.Response.SuppressFormsAuthenticationRedirect en true.

por ejemplo, en su CustomiseAttribute.cs personalizado

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (filterContext.HttpContext.Request.IsAjaxRequest()) { filterContext.Result = new JsonResult { Data = "_Logon_", JsonRequestBehavior = JsonRequestBehavior.AllowGet }; filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true; }

Opción 2. Si no usa .net 4.5

public class SuppressFormsAuthenticationRedirectModule : IHttpModule { private static readonly object SuppressAuthenticationKey = new object(); public static void Register() { DynamicModuleUtility.RegisterModule( typeof(SuppressFormsAuthenticationRedirectModule)); } public static void SuppressAuthenticationRedirect(HttpContext context) { context.Items[SuppressAuthenticationKey] = true; } public static void SuppressAuthenticationRedirect(HttpContextBase context) { context.Items[SuppressAuthenticationKey] = true; } public void Init(HttpApplication context) { context.PostReleaseRequestState += OnPostReleaseRequestState; context.EndRequest += OnEndRequest; } public void Dispose() { } private void OnPostReleaseRequestState(object source, EventArgs args) { var context = (HttpApplication)source; var response = context.Response; var request = context.Request; if (response.StatusCode == 401 && request.Headers["X-Requested-With"] == "XMLHttpRequest") { SuppressAuthenticationRedirect(context.Context); } } private void OnEndRequest(object source, EventArgs args) { var context = (HttpApplication)source; var response = context.Response; if (context.Context.Items.Contains(SuppressAuthenticationKey)) { response.TrySkipIisCustomErrors = true; response.ClearContent(); response.StatusCode = 401; response.RedirectLocation = null; } } }

y en web.config

<modules> <add name="SuppressFormsAuthenticationRedirectModule" type="SuppressFormsAuthenticationRedirectModule"/> </modules>

vea aqui para mas informacion


Para el middleware Identity, el redireccionamiento se puede deshabilitar eliminando en la opción LoginPath en Startup.Auth.cs:

public void ConfigureAuth(IAppBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions { ... LoginPath = new PathString("/Account/Login"), // Remove this line });


Utilizo el código simuler que arroja 404. Su código podría ser:

public ActionResult My() { if (User.Identity.IsAuthenticated == false) { return new HttpUnauthorizedResult(); } // ... other code ... }