将我的Action过滤器类更改为自定义授权属性

时间:2014-01-04 19:50:47

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

我正在使用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响应?

由于

1 个答案:

答案 0 :(得分:2)

这样的事情:

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 });
    }
}

要研究的几个链接:

希望这有帮助。