当用户尝试访问不应访问的内容时,我想显示一个页面。此限制是在自定义中间件中检查的。当中间件返回false并调用新控制器时,我不希望更改客户端url。
这是我的中间件检查:
public async Task Invoke(HttpContext context, IAutorisationService service)
{
var user = service.CreateUserModel(context);
var page = service.CreatePageModel(context);
context.Items.Add("CurrentUser", user);
if (service.UserAllowedToPage(user, page))
await _next.Invoke(context);
else
{
context.Response.Redirect("/Error/CustomError");
}
}
这是错误控制器:
public IActionResult CustomError()
{
if (!HttpContext.Items.TryGetValue("CurrentUser", out var o) || !(o is UserModel userModel))
{
return View();
}
if (userModel.IsSuperUser)
{
return View();
}
这里返回的视图都可以正常工作。
这是我的startup.cs(我现在在这里苦苦挣扎):
app.UseMvc(routes =>
{
//routes.MapRoute(
//name: "ErrorRoute",
//template: "{controller=Error}",
//defaults: new {controller = "Error", action = "CustomError"});
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
我在网上找到的任何组合似乎都无法正确实现。
更新
好的,所以我对政策没有进一步的了解。
我会尽力解释一下我的情况:
我在管道的末尾有一个自定义的中间件(就在app.UseMvc
之前)
该中间件具有异步Task Invoke方法,该方法在另一个类中调用布尔运算符。
现在,如果布尔值返回true,则中间件任务将执行:await _next.Invoke(HttpContext)
,并且如果该布尔值返回false,我希望中间件执行异常。
当引发异常时,我需要:app.UseExceptionHandler("/Error/CustomError");
或app.UseStatusCodePagesWithReExecute("/Error/CustomError");
捕获它并在ErrorController中激活CustomError操作,然后返回一个自定义视图。这有可能吗? (很抱歉,我的第一个问题还没有完成)
答案 0 :(得分:0)
您可以使用
返回错误视图return View("Error")
您可以检查所需的内容,如果出现问题,可以从主视图返回错误视图
答案 1 :(得分:0)
您不能重定向到页面,而无需更改URL。重定向实际上发生在客户端。服务器仅发送带有包含备用URL的Location
头的302响应。客户有责任实际请求该备用URL,这是浏览器默认执行的操作。结果,浏览器实际上将请求/Error/CustomError
。
您需要做的是直接从中间件返回实际的错误响应,以使URL保持原样。但是,实际上,中间件在这里是错误的方法。
相反,您应该使用内置的授权框架。您可以通过实现需求和处理程序,然后使用Authorize
属性引用该策略,将自定义策略应用于控制器/操作:
[Authorize(Policy = "MyPolicy")]
public IActionResult MyProtectedAction()
然后,当用户不满足策略要求时,他们将陷入异常处理中间件中,您可以在其中通过配置app.UseStatusCodePagesWithReExecute
来绑定自定义视图:
public class Startup
{
...
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStatusCodePagesWithReExecute("/error/{0}");
...
}
}
这将执行为/error/{0}
路由定义的控制器和操作,而不会影响URL(“ ReExecute”部分)。 {0}
位将被HTTP状态代码替换为401 Unauthorized
。因此,您实际上可以将操作绑定到/error/401
或使用/error/{statusCode}
之类的路由来捕获所有操作,然后在状态代码内分支以处理多种不同的错误类型。无论价格多少,这也是您提供自定义404页,500页等的方式。
有关更多信息,请参见: