MVC 3中的现场级安全性的最佳实践是什么

时间:2011-07-18 18:35:40

标签: asp.net-mvc-3

我正在构建一个将由几个不同组使用的MVC 3应用程序。在我的观点中,我正在使用所有HTML帮助程序来构建我的UI。 (例如Html.DropDownListFor(),Html.EditorFor()等。)

我需要根据用户的角色实现不同的安全性。让我们用一个人的例子:

我有一个看起来像这样的视图:

@Html.LabelFor(m=>m.FirstName): @Html.TextBoxFor(m=>m.FirstName) <br />
@Html.LabelFor(m=>m.LastName):  @Html.TextBoxFor(m=>m.LastName) <br />

@Html.LabelFor(m=>m.IsActive):  @Html.EditorFor(m=>m.IsActive)

我需要完成的事情是: 1.防止不在“管理员”角色的用户编辑任何字段。 2.如果“IsActive”为false,则阻止用户编辑名字/姓氏字段。

似乎我需要的是一种将行为注入内置辅助函数的方法。无论是那个,还是写我自己的。 StackOverflow中还有一些其他问题在讨论基于角色存储安全性的数据库模型,但对中间层没有任何帮助。

我正在尝试重复使用相同的视图。我真的需要多个观点吗?

2 个答案:

答案 0 :(得分:2)

创建自定义ModelMetaDataProvider。这将允许您利用业务规则引擎甚至简单的ACL实现来修改每个模型及其属性的元数据,然后才能将其转换为视图。然后内置帮助器通常在渲染字段时遵循元数据。例如,你创建一个字段ShowForEdit = false,因为当前用户没有访问权限,那么帮助程序将不会呈现该字段。

此技术有助于将逻辑排除在视图/表示层之外,并使您的视图更加干净整洁。在某些情况下,您可能需要构建一个自定义模板,以便根据元数据进一步控制控件的呈现,但它仍然比在视图中包含一堆if语句更清晰。

答案 1 :(得分:0)

这很容易。

@Html.LabelFor(m=>m.FirstName): @if(User.IsInRole("Administrator")) {Html.TextBoxFor(m=>m.FirstName)} else {Html.DisplayFor(m=>m.FirstName)} <br />
@Html.LabelFor(m=>m.LastName):  @if(User.IsInRole("Administrator")) {@Html.TextBoxFor(m=>m.LastName)} else {Html.DisplayFor(m=>m.LastName)} <br />

@if(User.IsInRole("Administrator")) {
    Html.LabelFor(m=>m.IsActive)<text>:</text>  Html.EditorFor(m=>m.IsActive)
}

但是,您可以通过这种方式遇到麻烦,因为您必须小心您的模型不包含您从普通用户隐藏的必填字段。

如果是这种情况,最好为admin / non-admin使用单独的ViewModel。如果你也使用EditorTemplates,你可能也会做得更好。