ASP.NET Core RazorPages中,我们可以在页面模型基类中重载OnPageHandlerExecuting方法。
下面的例子中,BaseModel继承自 PageModel,是所有页面模型的基类。
推荐方案:
在BaseModel.cs中,重载OnPageHandlerExecuting方法(看下面代码中的注释):
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();
}
}
}
上述文档中,在解释 Result 属性时,专门提到了这个事情:
在页面过滤器内将 Result 设置为非空值将使该页面和任何剩余的页面过滤器短路。
延伸阅读
===================
其实上述方案在6年前发布 AppBoxCore 时已经存在了,只不过在 AppBoxCore 中做的更加工程化,也更加清晰。
当前的需求是要求有些页面需要进行身份验证,而一些公开的页面不需要身份验证。
- 我们首先定义 CheckPowerAttribute 过滤器。
namespace AppBoxCore.Dapper
{
/// <summary>
/// AppBoxCore自定义权限验证过滤器
/// </summary>
public class CheckPowerAttribute : ResultFilterAttribute
{
/// <summary>
/// 权限名称
/// </summary>
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
这个文档也相关有参考价值,当时遇到一个报错:
服务器无法在发送 HTTP 标头之后追加标头
如果需要在 GET 请求中结束当前请求,也需要设置 new EmptyResult()。
- 然后需要进行身份验证的页面,在页面模型上定义此属性即可。
比如 Admin 目录下的 Config 页面:
[CheckPower(Name = "CoreConfigView")]
public class ConfigModel : BaseAdminModel
{
...
}