如何创建具有不同权限视图的页面

时间:2011-03-03 17:27:02

标签: c# asp.net asp.net-mvc-2 modeling

我需要为不同类型的用户创建不同的页面视图。 我已在此处问过:How to create pages with different permissions' views

即使Aldeel的回答有效,但对我来说这似乎不是最佳解决方案。我会解释原因。

我会尝试解释我需要非常详细的内容,并希望你们中的一些人能够帮助我:D

我需要展示不同的观点,但不仅如此。每个用户都可以访问页面的不同部分。

我举一个例子:

想象一下具有这种结构的页面'X'

Field A
Field B
Field C
Field D

当来自群组U1的用户G1访问网页X时,系统会在第X页上检查数据库是否有该群组的权限。用户U1可以看到Field AField B,但只能修改Field A

设置为无组访问页U2的用户X。系统会在页面X上检查其权限。用户U2可以查看和修改所有字段。

当来自群组U3的用户G2访问网页X时,系统会在第X页上检查数据库是否有该群组的权限。用户U3可以看到Field CField D,但无法修改任何内容。

我希望这很容易理解......

我找不到办法做到这一点,而不是用大量有关该特定用户权限的数据填充ViewData。在我的示例中,只有4个字段,但在我当前的项目中,我没有少于20个字段的屏幕。所以我想你可以看到它是多么丑陋而且没有生产力。

这个想法类似于社交网络,正如我所说的那样(facebook example)。当访问UserX页面的用户只能看到UserX允许他访问的内容时。

我真的很感激任何帮助。

最好的问候。

2 个答案:

答案 0 :(得分:4)

要做你想做的事,你不应该控制你的观点 - 你实际上必须保护你的控制器 - 而不是视图。您可以通过控制器属性执行此操作。类似的东西:

[Authorize]
public class MyController {
}

通过这样做,您可以保护整个控制器。如果用户未经过身份验证,则该控制器中的每个操作都不会响应(具体而言,他们将收到401响应)。您可以通过授权单个用户或单个角色来扩展此功能,如下面的示例所示:

[Authorize(Users="eestein,JasCav")
public class MyController {
}

[Authorize(Roles="Administrator")]
public class MyController {
}

在您的情况下,您可能不希望整个控制器都拥有授权。嗯,非常好,ASP.NET MVC提供了对身份验证的动作级控制。所以,你可以这样做:

public class MyController {

    public ActionResult Index() { }

    [Authorize(Roles="Administrator")]
    public ActionResult Admin() { }

}

使用这个想法,您可以控制用户在页面上看到的内容。您将要从操作中返回部分页面,以便可以加载页面的各个方面。例如,您可能有一个显示一些正常数据和一些秘密数据的视图。普通数据可以通过普通页面返回。秘密数据应作为页面内的部分视图返回。但是,如果发生401,您可以处理它而不显示任何内容。

这很简单。 .NET团队在设置它时做得很好,您不必单独检查控制器中的权限。我希望这有助于你开始。在线搜索有关如何使用“授权”属性的更多信息。

<强>更新 如果您拥有控制这些权限的页面管理员,则必须明智地设置Authorize属性的设置方式。这就是“角色”非常重要的地方(根据我上面的例子)。例如,如果管理员说“我要将John Doe添加到SpecialUser角色”,那么John Doe用户将能够访问将角色设置为SpecialUser的所有操作(如果确实如此)你系统中的一个角色。)

显然,您必须为管理员提供一些能够执行此操作的方法,并且Authorize属性可以完美地完成此操作。要查看谁对页面具有权限,您必须查询数据库以找出谁是哪个角色的一部分。这是一种考虑设置的方法:

  • 您可以控制操作的角色。
  • 您的管理员可以控制授予这些角色的人员。
  • 您始终可以检查(通过简单查询)查看谁被分配到哪个角色。然后,您可以(通过您对行动角色的了解)了解谁可以看到网站的哪个部分。

我希望这能澄清(我希望我能很好地理解你的问题)。我认为你想做的事情是可能的。

更新2 是的,这确实假设您的控制器上有静态组,并且必须以编程方式添加任何新组。我很想知道什么样的用例需要不同的权限类型来动态创建 - 似乎它会被滥用。无论如何,我没有解决方案。

至于部分观点如何运作......就像这样......

public class ProductController : Controller
{
    //
    // GET: /Index/
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Partial1()
    {
       return PartialView();
    }

    [Authorize]
    public ActionResult Partial2()
    {
       return PartialView();
    }
}

在Index.aspx文件中,您将拥有以下内容:

<%= Html.RenderAction("Partial1") %>
<%= Html.RenderAction("Partial2") %>

如果用户未获得授权,您可以处理第二个RenderAction,以便视图永远不会显示。 (您可以在控制器中检查它。)

希望澄清事情!我正在奔跑,所以我现在无法扩展它。

答案 1 :(得分:1)

我会推荐“附加”安全性;用户的权限以及他的任何组的权限总共可以提供他允许做的一系列事情。如果他没有明确许可做某些需要许可的事情,他就不被允许这样做。在您的情况下,在用户U1和组G1之间,有足够的权限授予用户查看字段A和字段B,以及编辑字段A.由于用户本身或通过其组,未明确授予权限编辑字段B或查看或编辑字段C和D,他没有这些权限。

我会通过在代码隐藏中放入一个方法来实现这种类型的权限,该方法将接受表示用户及其权限的对象,并将询问这些权限以确定字段的可见性。所有字段都应该以不可见的方式开始,这种方法将使它们可见和/或可编辑。

需要注意的事项:

  • 确保使用.NET服务器端工具显示/隐藏字段。如果在服务器端将字段的Visible属性设置为false,则呈现的页面甚至不会在HTML中包含该字段。相比之下,添加样式或使用JavaScript来隐藏属性会将它们保存在DOM和HTML中,这样一个人就可以“查看源代码”来查看以这种方式隐藏的字段。
  • 永远不要使用客户端代码来实现安全性。可以拒绝,禁用和/或操纵JavaScript,ActiveX控件等。显示数据的客户端代码还要求数据存在于页面源中的某个位置,这意味着通过查看页面源可以非常容易地找到它。
  • 出于同样的原因,不要相信不可编辑的字段不会更改其数据。使用FireBug等工具可以非常轻松地更改HTML和客户端代码。
  • 如果您从隐藏/禁用的所有内容开始并使其可见/启用,那么您的代码将更加安全,而不是以开放式访问和隐藏内容开始。如果你忘记隐藏新的东西,突然之间客户会看到一个他们不应该触摸的新领域。如果您忘记添加代码以根据权限显示新字段,您仍然需要修复它,但是利用不存在的字段要困难得多或者不可能。