繁体   English   中英

部署到IIS后,自定义授权属性不起作用

[英]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请求还是简单的页面刷新都无关紧要-

  1. 我将站点部署到本地IIS
  2. 登录该网站,转到主页-“ / Home”
  3. 右键单击“注销”链接,“在新选项卡中打开”-这可确保在注销会话时仍在当前选项卡上打开主页。
  4. 刷新主页。 现在,在这里,调试点应命中我覆盖的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM