如何使用ASP.Net MVC5和OWIN返回StatusCode 401

Ant*_*pod 2 asp.net-mvc angularjs owin asp.net-mvc-5 angular-ui-router

我想知道如何使用ASP.Net MVC5,我的IExceptionFilter,Microsoft.Owin和ui-router(https://github.com/angular-ui/ui-router)的实现.

我的情况是:当权限出现问题时,我会使用以下内容向客户端发送响应:

    public void OnException(ExceptionContext filterContext)
    {
        if (filterContext.Exception == null)
        {
            return;
        }

        ...

        filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        filterContext.Result = "Unathorized access";
    }
Run Code Online (Sandbox Code Playgroud)

请注意:我已将StatusCode代码设置为401.

要从服务器获取视图模板,我使用$ stateProvide请求Action方法.如您所知,$ stateProvide是ui-router的核心部分,可以处理$ stateChangeError.不幸的是,不是我的情况.

我需要使用Microsoft.Owin.由于某些原因,我的响应有StatusCode = 200(不是401)并且具有"X-Responded-JSON"标头:

X-Responded-JSON:{"status":401,"headers":{"location":"<URL>"}}
Run Code Online (Sandbox Code Playgroud)

以下是来自http://kevin-junghans.blogspot.de/2013/12/returning-401-http-status-code-on.html的引用"... OWIN和MVC 5中的安全管道已经改变,自定义属性不再返回401和403状态代码.而是返回200状态代码并在标题中插入一些其他信息......"

基本上,这意味着不会触发$ stateChangeError.

有人知道如何解决这个问题吗?谢谢.

Ant*_*pod 6

该解决方案实际上是在我添加到我的问题中的链接中提供的.以下是适用于我的解决方案:

public class StartupAuth
{
    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"));
    }

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

        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        var configuration = (IConfiguration)DependencyResolver.Current.GetService(typeof(IConfiguration));
        app.UseFacebookAuthentication(configuration.FacebookAppId, configuration.FacebookAppSecret);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我有StatusCode = 401并且触发了$ stateChangeError.