2013-11-17 5 views
8

Используя ASP.NET MVC 5, я хотел бы вернуть соответствующий код состояния HTTP для разных сценариев (401 для пользователя не аутентифицирован, 403, когда пользователь не имеет права на какой-либо ресурс и т. Д. .), затем обработайте их в jQuery.HttpStatusCodeResult (401) возвращает «200 OK»

Но проблема в том, что когда я пытаюсь вернуть 401, он всегда возвращает «200: OK». MVC 5 RC1 давал «302: Найдено» вместо 401, поэтому я мог использовать обходное решение (HttpStatusCodeResult(401) returns "302 Found"). Но теперь я перешел из MVC 5 RC1 в MVC 5, и это поведение изменилось. Теперь это всегда «200: OK». Поэтому мое обходное решение бесполезно, конечно, я не могу заменить ни на что другое.

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

    // ... other code ... 
} 

Как это решить?

+3

показать нам некоторые примеры кода, где используют 401 таким образом, мы можем помочь вам. Нет кода == нет помощи. – Haney

+0

Код в моем предыдущем вопросе, который я связал. Но теперь я буду вставлять его здесь, а также по вашему запросу. –

+1

Вы не должны явно проверять «User.Identity.IsAuthenticated». Аутентификация в ASP.NET MVC обычно выполняется с атрибутами; вам следует применить атрибут Authorize к вашему методу. –

ответ

0

Я использую simuler код возврата 404. Ваш код может быть:

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

Решение вопроса можно найти в http://kevin-junghans.blogspot.in/2013/12/returning-401-http-status-code-on.html

Вы должны изменить свой Startup класс как это:

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

} 

3

MVC 5+ Pip eline изменяет 401 кода ответа.

Вариант 1 С .net 4.5

вы можете установить HttpContext.Response.SuppressFormsAuthenticationRedirect истина.

например. в пользовательских AuthoriseAttribute.cs

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

Вариант 2. Если вы не используете .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; 
     } 
    } 
} 

и в web.config

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

See here for more info

0

идентичности промежуточное программное обеспечение, перенаправление может быть отключено путем удаления в опции LoginPath в Startup.Auth.cs:

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

В Statup.cs я должен был установить AutomaticChallenge в false. Как только я это сделал, он прекратил переадресацию URL (что привело к статусу 200) и дало мне статус 401, который я хотел.

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

Если вы установили некоторые печенья межплатформенное:

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 //<@@@@@@@ 
    }); 
} 
Смежные вопросы