• ASP.NET Core的全局拦截器(在页面回发时,如果判断当前请求不合法,不执行OnPost处理器)


    ASP.NET Core RazorPages中,我们可以在页面模型基类中重载OnPageHandlerExecuting方法。

    下面的例子中,BaseModel继承自 PageModel,是所有页面模型的基类。

    推荐方案:
    在BaseModel.cs中,重载OnPageHandlerExecuting方法(看下面代码中的注释):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public override void OnPageHandlerExecuting(PageHandlerExecutingContext context)
    {
        base.OnPageHandlerExecuting(context);
     
        if (IsPostBack)
        {
            // 回发请求时,检索请求数据或者Cookie,来验证当前访问是否有效。请求无效时,弹出错误提示,不再执行Page_Load和回发事件。
            if (!String.IsNullOrEmpty(Request.Query["error"]))
            {
                ShowNotify("身份验证失败!");
     
                // Setting Result to a non-null value inside a page filter will short-circuit the page and any remaining page filters.
                // 设置context.Result=UIHelper.Result(),可以中断页面继续执行(跳过接下来的 Page_Load 和回发事件)。
                context.Result = UIHelper.Result();
            }
        }
    }

     

    微软官方文档:https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.filters.pagehandlerexecutingcontext?view=aspnetcore-8.0

    上述文档中,在解释 Result 属性时,专门提到了这个事情:

     在页面过滤器内将 Result 设置为非空值将使该页面和任何剩余的页面过滤器短路。

     

    延伸阅读
    ===================
    其实上述方案在6年前发布 AppBoxCore 时已经存在了,只不过在 AppBoxCore 中做的更加工程化,也更加清晰。

    当前的需求是要求有些页面需要进行身份验证,而一些公开的页面不需要身份验证。

    1. 我们首先定义 CheckPowerAttribute 过滤器。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    namespace AppBoxCore.Dapper
    {
        ///
        /// AppBoxCore自定义权限验证过滤器
        ///
        public class CheckPowerAttribute : ResultFilterAttribute
        {
            ///
            /// 权限名称
            ///
            public string Name { get; set; }
             
            public override void OnResultExecuting(ResultExecutingContext filterContext)
            {
                HttpContext context = filterContext.HttpContext;
                // 权限验证不通过
                if (!String.IsNullOrEmpty(Name) && !BaseModel.CheckPower(context, Name))
                {
                    if (context.Request.Method == "GET")
                    {
                        BaseModel.CheckPowerFailWithPage(context);
     
                        // -修正越权访问页面时会报错[服务器无法在发送 HTTP 标头之后追加标头](龙涛软件-9374)。
                        filterContext.Result = new EmptyResult();
                    }
                    else if (context.Request.Method == "POST")
                    {
                        BaseModel.CheckPowerFailWithAlert();
                        filterContext.Result = UIHelper.Result();
                    }
                }
            }
     
        }
    }

     

    参考文档:http://stackoverflow.com/questions/9837180/how-to-skip-action-execution-from-an-actionfilter  

    这个文档也相关有参考价值,当时遇到一个报错:

    1
    服务器无法在发送 HTTP 标头之后追加标头

    如果需要在 GET 请求中结束当前请求,也需要设置 new EmptyResult()。

     

    2. 然后需要进行身份验证的页面,在页面模型上定义此属性即可。
    比如 Admin 目录下的 Config 页面:

    1
    2
    3
    4
    5
    [CheckPower(Name = "CoreConfigView")]
    public class ConfigModel : BaseAdminModel
    {
    ...
    }

      

  • 相关阅读:
    TVRNet网络PyTorch实现
    我们需要重新想象区块链的未来
    【金融分析】Python:病人预约安排政策 | 金融模拟分析
    再扩国产化信创版图!朗思科技与中科方德完成产品兼容性互认证
    matplotlib一点记录
    OpenCV 资料
    j2catche缓存整合框架
    【Node.js】npm和包
    04 运算符
    数据结构--双向链表(图文)
  • 原文地址:https://www.cnblogs.com/sanshi/p/18193981