基于权限的Html元素可见性,而不是MVC中的角色

时间:2014-10-22 08:11:35

标签: c# asp.net-mvc asp.net-authorization

我见过许多例子,可以使用以下内容在cshtml文件中切换html元素的可见性:

if (User.IsInRole("Admin"))
{
    <input type="button" value="Save" />
}

但是,是否可以实现以下内容:

// User has update permission to User objects
User.HasPermission("User", "Update")
{
    <input type="button" value="Save" />
}

我想在我的MVC应用程序中使用这两种方法,其中角色与许多权限相关联,权限也可以单独提供给用户。

一种方法是覆盖System.Security.Principal和System.Security.Identity,并在Global.asax Application_AuthenticateRequest方法集中:

object user = HttpContext.Current.Cache.Get(authTicket.Name);

MyIdentity identity = new MyIdentity((MyUser)user, true);
MyPrincipal principal = new MyPrincipal(identity);
Context.User = principal;
Thread.CurrentPrincipal = principal;

然后在cshtml文件中使用:

MyIdentity identity = (MyIdentity)User.Identity;
if (identity.User.HasClaim("User", "Update"))
{
    <input type="button" value="Save" />
}

这种方法的问题在于我必须在我需要检查权限的任何地方对MyIdentity执行此操作。

有更好,更有效的方法吗?我的目标是MVC3或MVC4。

-

编辑:

根据DavidG的建议,我开始研究扩展方法。这就是我想出的:

public static class PrincipalExtensions
{
    public static MyIdentity MyIdentity(this IPrincipal principal)
    {
        return principal.Identity as MyIdentity;
    }
}

我如何使用它?在一些例子中,我看到人们改变他们的web.config - 尝试 - 或插入控制器和controllerFactory,以及global.asax代码。到目前为止,我没有让MyIdentity在我的cshtml文件中可用。

-

EDIT2:

更多进展:我使用了此处的说明:http://rizzo7.blogspot.fi/2012/04/mvc-30-razor-custom-principal-and.html

得到它 - 有点 - 工作,现在我可以使用如下语法:

if (User.MyIdentity().User.HasClaim("User", "Update"))
{
    <input type="button" value="Save" />
}

但是,在Visual Studio中,我收到一条错误说明:

System.Security.Principal.IPrincipal'不包含'MyIdentity'的定义,并且没有扩展方法'MyIdentity'接受类型'System.Security.Principal.IPrincipal'的第一个参数可以找到(你错过了吗?使用指令或程序集引用?)

在我的View的Web.config中,我有:

  <system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Routing" />
    <add namespace="namespace.of.PrincipalExtensions"/>
  </namespaces>
</pages>

尽管出现错误,项目仍会正确编译并运行。在为每次可见性检查获取错误时进行开发和调试会很麻烦。我能做些什么吗?

-

EDIT决赛!

谢谢大家,我会回答我自己的最后一个问题;只需要确保cshtml看到扩展类的命名空间。 :)

我标记了DavidG的答案,因为它让我从正确的地方搜索并给了我最需要的东西。谢谢!

1 个答案:

答案 0 :(得分:2)

您可以使用扩展方法对其进行整理:

public static MyIdentity MyIdentity(this IPrincipal user)
{
    return (MyIdentity)User.Identity;
}

或HTML帮助:

public static MyIdentity MyIdentity(this HtmlHelper helper)
{
    return (MyIdentity)User.Identity;
}