[英]Custom authorize attribute doesn't work after deploying to IIS
我在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请求还是简单的页面刷新都无关紧要-
HandleUnauthorizedRequest
方法,并通过if / else条件,然后将我重定向到登录页面。 但事实并非如此! 它只是直接重定向到登录页面。 我想这甚至没有考虑我的自定义授权属性。 但是,当我从Visual Studio运行站点时,一切正常,控件以我的重写方法进入调试点,并通过if / else条件。
当您将网站部署到IIS时,默认情况下它将在IIS集成模式下运行。 通常这是最佳选择。 但这也意味着在授权检查期间,HTTP请求/响应模型没有完全初始化。 我怀疑这导致IsAjaxRequest()
在您的应用程序托管在IIS上时始终返回false
。
同样, 默认的HandleUnauthorizedRequest
实现如下所示:
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);
}
}
}
注意:上面的代码未经测试。 但这应该使您朝着正确的方向前进。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.