【问题标题】:How to verify user role before executing action?如何在执行操作之前验证用户角色?
【发布时间】:2017-07-10 00:00:38
【问题描述】:

我正在处理一个项目,其中一些用户可以担任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

然后我放弃了这个想法。

但后来我发现了异常处理程序属性和日志记录操作过滤器。

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

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

欢迎任何建议,在此先感谢。

【问题讨论】:

  • 您想限制一整套控制器,使其只能由一个角色访问吗?
  • @BillRuhl。假设一个带有按钮的表格列表可以更改每行的状态(这是我的示例)。 AdminReader 可以看到表列表(控制器中的PartialViewResult),但不能看到ChangeStatus(同一控制器中的JsonResult)。它几乎适用于每个控制器,无论是带有按钮来更改状态的列表,还是带有按钮来编辑值的模式。视图是可访问的,但方法不应该是
  • 我会在视图本身而不是在控制器中尝试 @if (User.Identity.IsAuthenticated && !User.IsInRole("AdminReader")){ //render button}。换句话说,如果用户的角色是“AdiminReader”,那么不要渲染按钮..

标签: c# asp.net-mvc


【解决方案1】:

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

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

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

但是,话虽如此,您仍然需要在每个页面上都有代码,根据用户的角色控制用户可以做什么和不可以做什么。没有什么神奇的方法可以解决这个问题。每当您想根据访问权限控制用户可以在页面上执行的操作时,您都需要在需要控制的每个部分中执行此操作的代码。

从您的示例中不清楚您要做什么,因为页面的返回值通常是要呈现的 HTML,但看起来您想要返回某种状态消息。我看不出如何将其复制到所有页面,因为页面本身需要呈现。

【讨论】:

  • AdminReader 能够访问:视图、部分、表格列表、模式、所有内容,但它们不能保存、编辑或ChangeStatus(如我的问题示例中所示)。跨度>
【解决方案2】:

我不完全确定我理解了你的问题,很抱歉,如果它关闭了:但是如果你想执行你的 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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多