如何在执行操作之前验证用户角色?

时间:2017-02-20 16:00:14

标签: c# asp.net-mvc

我正在开展一个项目,其中一些用户可以担任AdminReader角色。这些用户可以看到所有内容,但无法保存/编辑任何数据。

我知道我可以这样做:

public JsonResult ChangeStatus(int? id)
{
    // AdminReader validation
    if (base.User.isAdminReader)
    {
        return Json(new
        {
            Message = "You don't have privileges to alter data.",
            Success = false,
        }, JsonRequestBehavior.AllowGet);
    }

    // Function code

但我不想在所有项目函数中插入上述代码。

我以为我可以装饰我的方法,就像我们使用[HttpGet]一样。我也读过这个SO post

然后我放弃了这个想法。

但后来我发现了Exception Handler Attribute和一个日志动作过滤器。

是否有可能以某种方式将public void OnActionExecuting(ActionExecutingContext filterContext)与我的AdminReader验证结合起来?

我不知道这是否是解决问题的正确方法。此外,我不确定它是否真的有效。在这种情况下,最佳做法是什么?

欢迎任何建议,谢谢。

2 个答案:

答案 0 :(得分:0)

有很多方法可以做到这一点。

是的,属性只是元数据。但是,MVC框架中包含识别某些元数据并对其执行操作的代码。示例包括您提到的两个属性(ActionFilters和ExceptionFilters),还有AuthorizationFilters,这可能是您真正想要的。

AuthorizationFilters在ActionFilters之前运行,靠近MVC管道的开头,允许它们在页面实际呈现之前阻止访问。但是,如果您不需要,可以在页面呈现之前使用此点来执行特定操作。

然而,话说回来,你仍然需要在每个页面上都有代码来控制用户可以根据他们的角色做什么和不做什么。没有神奇的方法。每当您想要根据访问权限控制用户在页面上可以执行的操作时,您需要在需要控制的每个部分中执行此操作的代码。

从您的示例中不清楚您要执行的操作,因为页面的返回值通常是要呈现的HTML,但看起来您想要返回某种状态消息。我不知道如何将它复制到所有页面,因为页面本身需要渲染。

答案 1 :(得分:0)

我并不完全确定我理解了您的问题,如果关闭,请抱歉:但如果您想执行AdminReader逻辑,则可以编写自己的自定义属性,如下所示:

 public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
 {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            if (filterContext.Result is HttpUnauthorizedResult)
            {
                // Perform your unauthorized action here.
            }
        }
}

然后将该属性抛出到它应用的任何方法上(或者如果它应用于所有内容,您可以将它抛出整个Controller类)。像这样:

// The RoleSettings is a class of constants I defined that just contain strings
[AccessDeniedAuthorize(Roles = RoleSettings.AdminRole]
[HttpPost]
public ActionResult MyEditMethod()
{
   // Perform actions if they are in the AdminRole
   // If not authorized, it will do whatever you defined above in the 
   // AccessDeniedAuthorizeAttribute
}
相关问题