如何在ASP.NET MVC中全局授权用户并区分Ajax请求返回不同响应
实现ASP.NET MVC全局用户授权(区分Ajax/非Ajax请求)
刚好之前做过类似的需求,全局授权不用每个Action都加[Authorize],还要区分Ajax和非Ajax请求的不同处理,其实核心就是自定义一个授权过滤器,然后全局注册,再配合前端处理Ajax的未授权响应就行,一步步来:
步骤1:自定义全局授权过滤器
我们需要重写默认的AuthorizeAttribute,在HandleUnauthorizedRequest方法里区分请求类型:
public class GlobalAuthorizeAttribute : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { // 判断是否为Ajax请求 if (filterContext.HttpContext.Request.IsAjaxRequest()) { // Ajax请求返回JSON格式的未授权响应,带上状态码401 filterContext.Result = new JsonResult { Data = new { IsAuthorized = false, Message = "请先登录" }, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; filterContext.HttpContext.Response.StatusCode = 401; } else { // 非Ajax请求直接跳转到登录页(沿用默认逻辑) base.HandleUnauthorizedRequest(filterContext); } } }
这里的Request.IsAjaxRequest()会检查请求头里的X-Requested-With: XMLHttpRequest,这是jQuery等库发起Ajax请求时默认带的头,很可靠。
步骤2:注册全局过滤器
打开App_Start/FilterConfig.cs,把我们自定义的过滤器添加到全局过滤器集合里,这样所有Action都会自动应用授权检查:
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { // 添加全局授权过滤器 filters.Add(new GlobalAuthorizeAttribute()); filters.Add(new HandleErrorAttribute()); } }
注意:一定要给登录页的Action加上[AllowAnonymous]属性,不然会陷入无限跳转的死循环! 比如:
[AllowAnonymous] public ActionResult Login() { return View(); }
步骤3:前端处理Ajax未授权响应
当Ajax请求返回401状态码时,我们需要在前端弹出登录模态框。这里用jQuery的全局ajaxComplete事件来统一处理:
$(document).ajaxComplete(function(event, xhr, settings) { // 检查响应状态码是否为401未授权 if (xhr.status === 401) { try { var response = JSON.parse(xhr.responseText); if (!response.IsAuthorized) { // 弹出登录模态框(假设你页面里有id为loginModal的Bootstrap模态框) $('#loginModal').modal('show'); } } catch (e) { // 解析失败的话可以做降级处理,比如跳登录页 window.location.href = '/Account/Login'; } } });
如果你的模态框不是用Bootstrap的,替换成你自己的模态框显示逻辑就行。
一些额外注意事项
- 如果你的Ajax请求不是用jQuery发起的,记得手动在请求头里加上
X-Requested-With: XMLHttpRequest,不然Request.IsAjaxRequest()会判断错误。 - 可以根据需求扩展JSON返回的内容,比如加上当前请求的URL,登录成功后可以跳回原页面。
- 如果你有部分Action不需要授权,直接在对应的Action或Controller上加上
[AllowAnonymous]即可,它会覆盖全局的授权过滤器。
这样配置之后,所有页面都会自动应用授权检查,不用逐个Action配置,而且完美区分了Ajax和非Ajax请求的处理逻辑。
内容的提问来源于stack exchange,提问作者Joe herman
相关产品推荐
相关产品推荐

