【问题标题】:Redirect from AuthorizeCore to another controller with custom error message使用自定义错误消息从 AuthorizeCore 重定向到另一个控制器
【发布时间】:2017-08-28 13:20:54
【问题描述】:

所以我试图向用户显示一条消息,当他从无权查看的页面重定向时。示例:用户访问 www.mypage.com/users 并被重定向到 www.mypage.com/home。

我使用 MVC 模式,它是 asp.net Web 应用程序。 我重写 AuthorizeAttribute 并在 AuthorizeCore 方法中尝试这样做:

protected override bool AuthorizeCore(HttpContextBase httpContext)
        {


            if (false)//Here is custom logic that is working
            {
                string message = "You don't have an access to selected menu item.";
                var dataDict = HttpContext.Current.Session["__ControllerTempData"] as IDictionary<string, object>;
                if (dataDict == null)
                {
                    Dictionary<string, object> dictionary = new Dictionary<string, object>();
                    dictionary["myErrorMessage"] = message;
                    HttpContext.Current.Session["__ControllerTempData"] = dictionary;
                }
                else
                {
                    dataDict["myErrorMessage"] = message;
                    HttpContext.Current.Session["__ControllerTempData"] = dataDict;
                }

                _isAuthorized = false;

                httpContext.Response.Redirect("Home");                
            }
            else
            {
                _isAuthorized = base.AuthorizeCore(httpContext);
            }

            return _isAuthorized;
        }

然后我尝试从视图中访问它

var unauthorized_access_message = TempData["myErrorMessage"] as List <string> ?? new List<string>() ;

但它不起作用。我也尝试了this,但情况并非如此,因为我尝试访问一个控制器然后重定向到另一个控制器。 是否有任何解决方案可以将变量传递给视图或检查视图中的某些状态(如重定向原因)?

【问题讨论】:

    标签: asp.net httpcontext


    【解决方案1】:

    您能否覆盖OnAuthorization 而不是AuthorizeCore,在其中您可以直接从Controller 访问TempData

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (false)
        {
            filterContext.Controller.TempData["myErrorMessage"] =
                "You don't have an access to selected menu item.";
        }
        base.OnAuthorization(filterContext);
    }
    

    用法

    string unauthorized_access_message = (TempData["myErrorMessage"] ?? "").ToString();
    

    【讨论】:

    • 抱歉,这不起作用。我认为这是因为重定向。假设有人试图访问 Account 控制器,但没有权限(它会点击 OnAuthorization 并设置 tempdata),所以他将被重定向到 Home 控制器(它会再次点击 OnAuthorization 但之后没有那个 TempData不再)。至少当我尝试从 Home/Index 访问它时,它是空字符串。
    • 通常情况下,匿名用户应该被重定向到Login page而不是Home page,除非主页都需要匿名访问。
    • 问题是它不是匿名用户。我有自定义身份验证。因此用户已通过身份验证但未授权,假设管理员可以访问帐户/成员,他可以在其中获取成员列表。但如果会员尝试访问它,他必须转到主页/索引并查看“无权限”通知。
    • 直接访问会话状态怎么样?检索消息后,在此处插入 null 值。 var unauthorized_access_message = Session["ErrorMessage"] as List &lt;string&gt; ?? new List&lt;string&gt;(); Session["ErrorMessage"] = null;
    • 由于某种原因,会话不能正常工作。试过了。但我找到了解决方案并将其作为答案发布。
    【解决方案2】:

    我通过使用 Cookie 解决了这个问题。

    在 CustomAuthorizeAttribute:AuthorizeAttribute 类中设置 cookie:

    protected override bool AuthorizeCore(HttpContextBase httpContext)
                {
    
                    if (false)
                    {
                        HttpCookie mycookie= new HttpCookie("unauthorize_error", "You do not have access to requested link.");
                        httpContext.Response.SetCookie(mycookie);
                        httpContext.Response.Redirect("Home");
                        return false;
                    }
                    else
                    {
                        return base.AuthorizeCore(httpContext);
                    }
                }
    

    然后在控制器中:

    string cookieValue = string.Empty;
                if (Request.Cookies["myCookieName"] != null
                    && !string.IsNullOrEmpty(Request.Cookies["myCookieName"].Value))
                {
                    cookieValue = Request.Cookies["myCookieName"].Value;
                    var myCookie = new System.Web.HttpCookie("myCookieName");
                    myCookie.Expires = System.DateTime.Now.AddDays(-1d);
                    Response.Cookies.Add("myCookieName");
                }
    var messages = TempData["mytemperror"] as List<string> ?? new List<string>();
                messages.Add(message);
                TempData["myTempError"] = messages;
    

    终于看到了:

    var errorMessage = TempData["myTempError"] as List<string> ?? new List<string>();
    

    【讨论】:

      猜你喜欢
      • 2020-12-16
      • 1970-01-01
      • 2016-07-04
      • 2019-10-17
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多