【问题标题】:Changing my Action filter class to be a Custom authorization attribute将我的操作过滤器类更改为自定义授权属性
【发布时间】:2014-01-04 19:50:46
【问题描述】:

我正在开发一个 asp.net mvc4 Web 应用程序,并且我有以下操作过滤器类,它实现了自定义授权:-

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]

    public class CheckUserPermissionsAttribute : ActionFilterAttribute
    {

        public string Model { get; set; }
        public string Action { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // var user = User.Identity.Name; // or get from DB
            int value = 0;
            Repository repository = new Repository();

            if (!repository.can(ADusername,Model,value )) // implement this method based on your tables and logic
            {if (filterContext.HttpContext.Request.IsAjaxRequest())
                {

                    var viewResult = new JsonResult();
                    viewResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
                    viewResult.Data = (new { IsSuccess = "Unauthorized", description = "Sorry, you do not have the required permission to perform this action." });
                    filterContext.Result = viewResult;
               }
                else
                {
                    var viewResult = new ViewResult();

                    viewResult.ViewName = "~/Views/Errors/_Unauthorized.cshtml";
                    filterContext.Result = viewResult;
                }

            }

            base.OnActionExecuting(filterContext);
        }
    }
}

我在调用动作方法之前使用actino过滤器,如下所示:-

[CheckUserPermissions(Action = "Edit", Model = "Router")]
        public ActionResult Create(int? rackid)
        {

但我需要更改操作过滤器类,使其成为由 AuthorizeAttribute 驱动的类,所以任何人都可以建议这样做需要哪些步骤吗?

编辑

我修改了我的操作过滤器类以使用 AuthorizeAttribute 如下,但我之前的缓存问题仍然存在。就好像授权用户访问操作方法一样,如果未经授权的用户访问相同的操作方法,他将能够读取他没有权限的缓存数据....这就是我想改变我的原因动作过滤器成为授权属性。我当前的授权属性是:-

public class CheckUserPermissionsAttribute : AuthorizeAttribute
    {

        public string Model { get; set; }
        public string Action { get; set; }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {

         // code goes here
            if (!repository.can(ADusername,Model,value )) // implement this method based on your tables and logic
            {
               // filterContext.Result = new HttpUnauthorizedResult("You cannot access this page");

                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {

                    var viewResult = new JsonResult();
                    viewResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
                    viewResult.Data = (new { IsSuccess = "Unauthorized", description = "Sorry, you do not have the required permission to perform this action." });
                    filterContext.Result = viewResult;
                //    filterContext.HttpContext.Response.StatusCode = 400;

                    //filterContext.Result = new HttpUnauthorizedResult("You cannot access this page");

                }
                else
                {
                    var viewResult = new ViewResult();

                    viewResult.ViewName = "~/Views/Errors/_Unauthorized.cshtml";
                    filterContext.Result = viewResult;
                }

            }

            base.OnAuthorization(filterContext);
        }
    }
}

那么我目前的方法是否有效?请记住我正在根据请求类型返回未经授权的视图或 JSON,而不是返回 401 http 响应?

谢谢

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-mvc-4


    【解决方案1】:

    类似这样的:

    public class CheckUserPermissionsAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            bool authorized = /* your logic here */;
    
            if (!authorized) 
                base.HandleUnauthorizedRequest(filterContext);
        }
    }
    

    现在,要配置自定义错误页面(“未授权”),您可能需要在 web.config 文件中提供以下内容:

    <system.webServer>
        <httpErrors errorMode="Custom" existingResponse="Replace">
            <remove statusCode="403" subStatusCode="-1" />
            <error statusCode="403" path="/error/403" responseMode="ExecuteURL" />
        </httpErrors>
    </system.webServer>
    

    现在,路由:

    routes.Add("Error", new Route("error/{statusCode}",
        new { controller = "Error", action = "Details" }));
    

    最后是控制器:

    public class ErrorController : Controller
    {
        public ActionResult Details(int statusCode)
        {
            return View(new { StatusCode = statusCode });
        }
    }
    

    几个学习链接:

    希望这会有所帮助。

    【讨论】:

    • 感谢您的回复,但是拥有 ErrorController 类的想法是什么?我还能从 cusotm Iauthorization 过滤器类返回未经授权的视图吗??
    • 是的,您可以,实际上,这可能是一种更好的方法(没有重定向,因此更适合 SEO)。另一方面,当您想要封装许多与错误相关的操作(例如故障排除操作、联系表单等)时,拥有一个专用控制器会很有用
    • @johnG 我认为您应该从您的授权过滤器中返回正确的 HTTP 状态代码 (403)(例如,通过使用 HandleUnauthorizedRequest),而不是仅仅呈现包含错误消息的视图。这不仅会使行为更加正确和透明,而且还可能帮助您解决用户代理缓存当前200 OK 响应的问题。
    • 但我需要显示自定义错误消息,如果是正常的 http 则需要完整视图,或者如果请求是 ajax 请求则返回 JSON。但是重新调整 403 不允许我这样做?
    • 会的。您可以使用httpErrors 配置部分(使用existingResponse 而不是Replace)提供完整视图,并在通过AJAX 发出请求时仍然通过JsonResult(我自己没有尝试过后者,但记得我的一位同事最近在做类似的事情)。请记住以正确的 HTTP 状态响应,不要混淆用户代理 ;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 2016-10-27
    • 1970-01-01
    相关资源
    最近更新 更多