如何使授权属性返回自定义 403 错误页面而不是重定向到登录页面 [英] How to make Authorize attribute return custom 403 error page instead of redirecting to the Logon page

查看:27
本文介绍了如何使授权属性返回自定义 403 错误页面而不是重定向到登录页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[Authorize] 属性是很好用的 MS 发明,希望它能解决我现在遇到的问题

[Authorize] attribute is nice and handy MS invention, and I hope it can solve the issues I have now

更具体地说:

当当前客户端未通过身份验证时 - [Authorize] 从安全操作重定向到登录页面,登录成功后 - 将用户带回来,这很好.

When current client isn't authenticated - [Authorize] redirects from secured action to logon page and after logon was successful - brings user back, this is good.

但是当当前客户端已经通过身份验证但没有被授权运行特定操作时 - 我需要的只是显示我的常规 403 页面.

But when current client already authenticated but not authorized to run specific action - all I need is to just display my general 403 page.

是否可以不移动控制器主体内的授权逻辑?

Is it possible without moving authorization logic within controller's body?

更新:我需要的行为在语义上应该等于这个草图:

Update: The behavior I need in should be semantically equals to this sketch:

public ActionResult DoWork()
{
    if (!NotAuthorized())
    {
        // this should be not redirect, but forwarding 
        return RedirectToAction("403");         
    }

    return View();
}

so - 不应该有任何重定向,url 应该保持不变,但页面内容应该替换为 403-page

so - there should no any redirect and url should be stay the same, but contents of the page should be replaced with 403-page

更新 2:我以这种方式实现了草图:

Update 2: I implemented sketch in this way:

[HandleError]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }

    [CustomActionFilter]
    public ActionResult About()
    {
        return View();
    }

    public ActionResult Error_403()
    {
        return Content("403");
    }
}

public class CustomActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.Result = new ContentResult { Content = "403" };
    }
}

并且无法获得如何正确地将执行转发到 HomeController.Action_403() 所以它显示 403.

And can't get how to properly forward execution to HomeController.Action_403() so it display 403.

更新 3:

filterContext.Result = new ViewResult() { ViewName = "Error_403" };

所以这是关于如何呈现特定视图模板的答案......但仍然不知道如何运行另一个控制器 - 无论如何,这已经足够好的解决方案了.

so this is an answer on how to render specific view template... but still have no idea how to run another controller - anyway, it's enough good solution.

推荐答案

您应该能够创建自己的类,该类派生自 AuthorizeAttribute 并覆盖 AuthorizeCore 方法来提供你想要的授权机制,这样您就可以通过使用属性而不是将其移动到控制器中来应用您的自定义授权代码.

You should be able to create your own class that derives from AuthorizeAttribute and override the AuthorizeCore method to provide the authorization mechanism that you want, so that you can apply your custom authorization code by using an attribute instead of moving it into the controller.

如果您需要对授权进行更细粒度的控制,那么我建议您创建 IActionFilter 接口(在属性上,然后将该属性应用于您的方法).这将允许您在调用进入控制器之前拦截它们,并在调用控制器方法之前提供替代操作.

If you need more fine-grained control over authorization, then I recommend that you create an implementation of the IActionFilter interface (on an attribute, then apply the attribute to your methods). This will allow you to intercept calls before they go to the controller, and provide alternate actions before your controller method is called.

这是通过实现 IActionFilter 接口上的OnActionExecuting 方法.如果您的逻辑确定您根本不应该调用控制器,并且您想要提供 ActionResult 被处理,然后您将设置 Result 属性ActionExecutingContext 实例传入方法.通过这样做,该 ActionResult 被处理而不是去控制器方法来获取 ActionResult.

This is achieved by implementing the OnActionExecuting method on the IActionFilter interface. If your logic determines that you should not make the call to the controller at all, and you want to provide an ActionResult to be processed instead, then you would set the Result property on the ActionExecutingContext instance passed into the method. By doing this, that ActionResult is processed instead of going to the controller method to get an ActionResult.

如果要返回 403 错误代码,则不能使用 ContentResult 类.您将必须创建自己的从 ActionResult 派生的类并覆盖 ExecuteResult 方法来设置 StatusCode 属性HttpResponseBase 到 403,像这样:

If you want to return a 403 error code, then you can't use the ContentResult class. You will have to create your own class that derives from ActionResult and override the ExecuteResult method to set the StatusCode property on the HttpResponseBase to 403, like so:

internal class Http403Result : ActionResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        // Set the response code to 403.
        context.HttpContext.Response.StatusCode = 403;
    }
}

public class CustomActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.Result = new Http403Result();
    }
}

当然,您可以将 Http403Result 类泛化为接受您想要返回的状态代码的构造函数,但概念保持不变.

Of course, you can generalize the Http403Result class to take a constructor which will accept the status code that you want to return, but the concept remains the same.

这篇关于如何使授权属性返回自定义 403 错误页面而不是重定向到登录页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆