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

标签 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 - 尝试 - 或者干预 Controller 和controllerFactory以及global.asax代码。到目前为止,我还没有让 MyIdentity 在我的 cshtml 文件中可用。

--

编辑2:

更多进展:我使用了此处的说明: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”的定义,并且找不到接受“System.Security.Principal.IPrincipal”类型的第一个参数的扩展方法“MyIdentity”(您是否缺少使用指令还是程序集引用?)

在我的 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>

尽管出现错误,项目仍可以正确编译并运行。开发和调试时每次可见性检查都会出错,这将是一件痛苦的事情。我能做些什么吗?

--

编辑-最终!

谢谢大家,我来回答我自己的最后一个问题;只需确保 cshtml 可以看到扩展类的 namespace 。 :)

我标记了 DavidG 的答案,因为它让我从正确的地方进行搜索,并为我提供了我需要的大部分内容。谢谢!

最佳答案

您可以使用扩展方法来整理它:

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

或者 HTML 帮助器:

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

关于c# - Html 元素可见性基于权限,而不是 MVC 中的角色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26502924/

相关文章:

c# - 基于ctor参数构建Autofac组件

c# - System.Security.Cryptography.HMACSHA1 存在于具有相同命名空间的两个程序集中

c# - 如何使用 ajax 将文件上传到 asp.net mvc Controller 操作

c# - 循环遍历 Razor 中的模型内容

c# - 使用枚举和 Entity Framework 脚手架从模型创建下拉列表?

c# - 在 AuthorizationHandler 中使用 `await`

c# - Hashtable.OnDeserialization

asp.net-mvc - ASP.NET MVC - 从单个 Controller 操作返回不同的 View 是一个坏主意吗?

c# - 多个 Asp.net Web 应用程序的授权

asp.net - 通过 web.config 授权仅允许匿名用户