我已经覆盖了我的asp.net mvc应用程序中的HandleUnauthorizedRequest
方法,以确保它向未经授权的ajax调用发送401响应,而不是重定向到登录页面。当我在本地运行它时,这非常好用,但是一旦我部署到IIS,我的被覆盖的方法就不会被调用。调试点根本没有触及我的方法,并立即被重定向到登录页面。
这是我的代码:
public class AjaxAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
filterContext.Result = new JsonResult
{
Data = new
{
success = false,
resultMessage = "Errors"
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
filterContext.HttpContext.Response.End();
base.HandleUnauthorizedRequest(filterContext);
}
else
{
var url = HttpContext.Current.Request.Url.AbsoluteUri;
url = HttpUtility.UrlEncode(url);
filterContext.Result = new RedirectResult(ConfigurationManager.AppSettings["LoginUrl"] + "?ReturnUrl=" + url);
}
}
}
我在控制器上声明了属性[AjaxAuthorize]
。一旦将其部署到IIS,会有什么不同?
更新 这是我测试的方式,非常简单,在登录会话到期后它是ajax请求还是简单页面刷新无关紧要 - < / p>
HandleUnauthorizedRequest
方法,然后通过
if / else条件然后将我重定向到登录页面。但它
没有按&#39;吨!它只是简单地重定向到登录页面。我&#39;米
认为它甚至没有考虑我的自定义授权属性。当我从visual studio运行网站时,一切正常,控件在我的重写方法中进入调试点并进入if / else条件。
答案 0 :(得分:0)
将网站部署到IIS时,默认情况下它将在IIS集成模式下运行。这通常是最好的选择。但这也意味着HTTP请求/响应模型在授权检查期间未完全初始化。我怀疑当您的应用程序托管在IIS上时,这会导致IsAjaxRequest()
始终返回false
。
此外,default HandleUnauthorizedRequest
implementation看起来像这样:
protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
filterContext.Result = new HttpUnauthorizedResult();
}
实际上,通过调用base.HandleUnauthorizedRequest(context)
,您将覆盖使用默认JsonResult
实例设置的HttpUnauthorizedResult
实例。
有一个原因可以称为过滤器。它们用于过滤进入逻辑的请求,而不是用于实际执行该逻辑。处理程序(ActionResult
派生类)应该完成工作。
要实现此目的,您需要构建一个单独的处理程序,以便过滤器执行的逻辑等待,直到HttpContext
完全初始化为止。
public class AjaxAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new AjaxHandler();
}
}
public class AjaxHandler : JsonResult
{
public override void ExecuteResult(ControllerContext context)
{
var httpContext = context.HttpContext;
var request = httpContext.Request;
var response = httpContext.Response;
if (request.IsAjaxRequest())
{
response.StatusCode = (int)HttpStatusCode.Unauthorized;
this.Data = new
{
success = false,
resultMessage = "Errors"
};
this.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
base.ExecuteResult(context);
}
else
{
var url = request.Url.AbsoluteUri;
url = HttpUtility.UrlEncode(url);
url = ConfigurationManager.AppSettings["LoginUrl"] + "?ReturnUrl=" + url;
var redirectResult = new RedirectResult(url);
redirectResult.ExecuteResult(context);
}
}
}
注意:以上代码未经测试。但这应该让你朝着正确的方向前进。