在ViewModel中检查mvc安全角色



这是良好的安全实践把安全相关的属性在ViewModel,在视图中使用,即显示/隐藏"东西"取决于用户的角色?

例如:

ViewModel属性AdminRole。在控制器(User.IsInRole)中设置它的值,然后在视图中访问属性:if (Model.AdminRole) {show admin stuff…}

我读过其他SO帖子和(一些)人正在这样做,但质疑这是否安全,即在ViewModel中暴露安全属性。如果有更好、更安全的方法,请告诉我。

离题,但相关:恕我直言,这比呼叫User要好得多。

如果通过"ViewModel"你指的是用于MVC视图的dto(而不是MVVM框架中的ViewModel),那么不,这不是一个好的设计。

首先,从安全角度来看,这是一个糟糕的设计,因为:

  1. 你依靠你的视图实际上强制安全规则(例如通过检查AdminRole有条件地呈现内容)。这很难有效地测试或审查。

  2. 你冒着无意中泄露私人安全信息给客户端的风险,由于漏洞或只是草率的编码。

  3. 如果没有适当的卫生处理,您将有可能意外地将此属性用于POST, PUT或其他"写"操作。

但更重要的是,从MVC的角度来看,这是一个糟糕的设计,因为它错过了视图模型应该是什么。

视图模型意味着包含关于如何显示视图的信息。它们应该抽象业务逻辑,否则它们会出现在视图中,而不仅仅是传递给

对于这种情况,一个更好的设计是这样的:

ViewModel

public class IndexViewModel
{
    public bool CanDeleteItems { get; set; }
    public bool IsAdminMenuVisible { get; set; }
    // Other properties...
}
控制器

public ActionResult Index()
{
    return View(new IndexViewModel
    {
        CanDeleteItems = User.IsInRole("ContentManager"),
        IsAdminMenuVisible = User.IsInRole("Administrator"),
        // Other properties...
    });
}
<<p> 视图/strong>
@if (Model.IsAdminMenuVisible)
{
    <!-- Markup for admin menu -->
}
@foreach (var item in Model.Items)
{
    <!-- Markup for item -->
    <button type="submit"  @((Model.CanDeleteItems) ? "disabled" : "")>Delete</button>
}
这里的想法是ViewModel只包含特定于视图本身的属性。视图不能决定在什么业务条件下某个元素是可见的、禁用的,等等。视图模型将使用以绑定到的特定视图元素命名的属性,准确地告诉该显示什么以及何时显示。

这也有利于可维护性。如果你决定用户应该能够删除项目,如果他们有"ContentManager"或"Administrator"的角色会发生什么?在你的版本中,你最终会修改视图;在上面的版本中,您只需要修改控制器。如果您发现自己不得不修改视图,而不是为了改变外观和感觉,这意味着您在体系结构中犯了一个错误。安全检查应该在控制器中进行。


注意,根据您的体系结构风格,您也可以在ViewModel中实现这些作为派生属性,例如:
public class IndexViewModel
{
    private readonly IPrincipal user;
    public IndexViewModel(IPrincipal user)
    {
        this.user = user;
    }
    public bool CanDeleteItems
    {
        get { return user.IsInRole("ContentManager"); }
    }
    public bool IsAdminMenuVisible
    {
        get { return user.IsInRole("Administrator"); }
    }
}

这是一种更面向对象的设计,同样可以接受,因为视图模型实际上并不向视图公开底层规则,并且与控制器一样可测试。就像我上面说的,这更多的是个人偏好的问题,以及你是否希望你的ViewModels是智能的(如MVVM)还是只是愚蠢的dto(更MVC风格)。

如果你的ViewModel被传递到你的动作方法和变量赋值是由模型绑定然后,是的,它可能被劫持使用大规模分配漏洞。如果这是一个问题,我将使用任何其他方法来获取数据到您的视图。

无论您使用哪种方法,您都将使用User.IsInRole来确定是否应该显示/隐藏"stuff"。

除了您描述的两种方法(设置ViewModel属性或使用User)。IsInRole在视图中直接),我能想到的传递值的唯一其他方法是使用ViewBag, ViewData, Session, Cookie.....所有这些方法的工作原理基本相同。

我怎么做的:

在我的视图开始时,我使用User.IsInRole,然后将值保存到一个本地属性中,然后在页面中进一步检查以显示/隐藏内容

相关内容

  • 没有找到相关文章

最新更新