需求:
    在默认创建的Asp.Net MVC项目中(这里使用VS2013),需要手动返回一个401响应码给浏览器。我们的代码可能是下面这样子的。
 
  1.          public ActionResult UnauthorizedAccess()
    {
    return new HttpStatusCodeResult((int)HttpStatusCode.Unauthorized);
    }
 
实际的效果却和预期的不太一样,如果我们是通过地址栏直接访问这个Action,可以看到请求被重定向到登录页面了
 
 
如果通过Ajax的方式进行访问,可以看到直接返回了一个200的响应码
 
因为当前创建的MVC项目默认使用的是一个叫CookieAuthentication的OWIN中间件来实现身份认证的功能的,该中间件中会将401响应码进行特殊处理,所以导致我们无法手动返回401响应码。
 
Startup类中的代码: 
  1.              // 使应用程序可以使用 Cookie 来存储已登录用户的信息
    // 并使用 Cookie 来临时存储有关使用第三方登录提供程序登录的用户的信息
    // 配置登录 Cookie
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider
    {
    // 当用户登录时使应用程序可以验证安全戳。
    // 这是一项安全功能,当你更改密码或者向帐户添加外部登录名时,将使用此功能。
    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
    validateInterval: TimeSpan.FromMinutes(),
    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
    }
    });
 
 
 
所以如果你使用上述的中间件(使用其他的身份认证的组件也可能会存在重写401响应码的行为),那么就无法手动返回401响应码
 
如果需要手动返回401响应码,那么就需要在Asp.Net的生命周期中对相应做一些修改,查阅MSDN的资料可以看到PreSendRequestHeaders事件中比较适合做这个操作。
 
 
在Global中我们添加如下方法,在PreSendRequestHeaders事件中插入我们自己的代码,将响应码设置为我们预期想要的值
  1.          public void Application_PreSendRequestHeaders(object sender, EventArgs e)
    {
    //处理401响应被多个框架重写的问题
    var values = Response.Headers.GetValues(ForceHttpStatusCodeResult.ForceHttpUnauthorizedHeaderName);
    if (values != null && values.Contains(ForceHttpStatusCodeResult.ForceHttpUnauthorizedHeaderValue))
    {
    Response.ClearHeaders();
    Response.StatusCode = (int)HttpStatusCode.Unauthorized;
    }
    }
 
 
由于请求到这里的时候,响应码已经被重写,所以我们通过一个自定义的请求头来标识当前请求是一个要被手动发送给客户端的401响应
 
     /// <summary>
/// 强制返回指定的响应码
/// 401响应码会被MVC框架和OWIN授权认证的中间件给重写
/// </summary>
public class ForceHttpStatusCodeResult : HttpStatusCodeResult
{ public const string ForceHttpUnauthorizedHeaderName = "ForceHttpUnauthorizedHeader";
public const string ForceHttpUnauthorizedHeaderValue = "true"; public ForceHttpStatusCodeResult(int state)
: this(state, "")
{ } public ForceHttpStatusCodeResult(int state, string statusDescription)
: base(state, statusDescription)
{
if (state == (int)HttpStatusCode.Unauthorized)
{
SetForceHttpUnauthorizedHeader();
}
} private void SetForceHttpUnauthorizedHeader()
{
System.Web.HttpContext.Current.Response.AddHeader(ForceHttpUnauthorizedHeaderName, ForceHttpUnauthorizedHeaderValue);
}
}
 
 
此时我们在Action中就可以返回我们需要的任意响应码了
  1.          public ActionResult UnauthorizedAccess()
    {
    return new ForceHttpStatusCodeResult((int)HttpStatusCode.Unauthorized);
    }
 
Ajax请求结果:
 
 
 
下载:
   示例代码
 
 
参考资料:
 
 
 

最新文章

  1. sql查删更
  2. sqlite like 通配符 ,匹配区分大小写(默认不区分大小写)
  3. windows7 编译boost1.54
  4. 翻译-Salt与Ansible全方位比较
  5. 攻城利器 —— Carthage简单介绍
  6. 漫谈计算摄像学 (一):直观理解光场(Light Field)
  7. Codeforces Round #128 (Div. 2)
  8. 在内部架设NuGet服务器
  9. jstack(Stack Trace for Java)
  10. 确定比赛名次(map+邻接表 邻接表 拓扑结构 队列+邻接表)
  11. 将网页中的html代码的table保存成word文件
  12. MYBATIS 无效的列类型: 1111
  13. android开发解决Error:Execution failed for task &#39;:app:transformDexArchiveWithExternalLibsDexMergerForDebug&#39;. &gt; java.lang.RuntimeException: java.lang.RuntimeException: c.....
  14. ASP.NET上传文件到远程服务器(HttpWebRequest)
  15. HTTP请求报文解剖
  16. 不可变对象和Biulder模式(面试问题)
  17. 第十二次oo作业
  18. https://scrapingclub.com/exercise/detail_cookie/
  19. hdu 1558 (线段相交+并查集) Segment set
  20. 怎样在 fedora 28 上 打开 .jnlp 文件

热门文章

  1. Compilation failed: this version of PCRE is not compiled with PCRE_UTF8 support at offset 0
  2. ASPXGridView用法
  3. STL容器迭代器失效分析
  4. IRS-P6数据介绍
  5. Java中可变长参数的使用及注意事项
  6. 【MVC】ASP.NET MVC中实现多个按钮提交的几种方法
  7. JAVA语法细节(1)
  8. gcov源码,供学习使用。
  9. c++ string 转GUID及反转
  10. 如何:通过对字符串应用 HTML 编码在 Web 应用程序中防止脚本侵入