部署到IIS后,自定义授权属性不起作用
我在我的asp.net mvc应用程序中覆盖了HandleUnauthorizedRequest
方法,以确保它向未经授权的Ajax调用发送401响应,而不是重定向到登录页面。当我在本地运行它时,它的工作状态非常好,但是我部署到IIS后,我的重写方法不会被调用。调试点根本不打我的方法,并立即被重定向到登录页面。部署到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请求或一个简单的页面刷新后登录会话已过期 -
- 我部署将该网站放到我的本地IIS上
- 登录网站,进入主页 - “/ Home”
- 右键单击“注销”链接,“在新选项卡中打开” - 确保主页仍在当前标签上打开,而 会话被记录ou吨。
- 刷新主页。现在在这里,调试点应该打开我覆盖的
HandleUnauthorizedRequest
方法,并通过 if/else条件,然后将我重定向到登录页面。但它 不!它只是简单地重定向到登录页面。我是 认为它甚至没有考虑我的自定义授权属性。
但是,当我从Visual Studio运行该网站时,一切正常,控制进入我的覆盖方法的调试点,并通过if/else条件。
当您将您的网站部署到IIS时,默认情况下它将在IIS集成模式下运行。这通常是最好的选择。但这也意味着HTTP请求/响应模型在授权检查期间未完全初始化。我怀疑这导致IsAjaxRequest()
在您的应用程序托管在IIS上时始终返回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);
}
}
}
注:上面的代码是未经测试。但是这应该让你朝着正确的方向前进。
'一旦部署到IIS后会有什么不同?'''ConfigurationManager.AppSettings [“LoginUrl”]' - 你检查了你的配置文件吗? – NightOwl888
是的,我检查,它指向“帐户/登录”。但问题是,在部署到IIS后,即使我完全删除了“LoginUrl”的配置设置,它仍然会重定向到“帐户/登录”,该控件甚至不会输入我的自定义属性的'HandleUnauthorizedRequest'方法只有在我部署之后。我尝试在调试和发布配置中部署,但同样的问题 –