ASP.NET MVC - 如何根据已登录的用户角色权限隐藏或显示链接/按钮?

26

我正在使用ASP.NET MVC4。

这是我的用户角色。

1. Administrator
2. L1 Admin
3. L2 Admin

管理员组用户拥有设置权限(包括添加和权限设置)。

如果一个用户是管理员组的成员,他只能看到与上述设置相关的菜单。

我有一个菜单表格,其中包含菜单详细信息。根据当前用户的角色显示一些功能,如删除、编辑,而这些功能不在顶部菜单中可用。删除、编辑链接放置在表格内列出数据时。对于此类条目,IsVisible 值为 false。

MenuID - MenuName - Controller - Action - ParentID - IsVisible

我有一个roleMenu表,其中包含分配给每个角色的菜单。

RoleID - MenuID

如果管理员登录,他可以看到所有菜单。 如果L1Admin登录,他只能看到分配给他的菜单。

我创建了一个用于认证的自定义属性,并在此之后查询数据库,根据控制器和操作(表Menu连接RoleMenu)获取用户的权限。因此,如果用户尝试通过在浏览器中键入URL来访问操作,则可以限制请求。

如果我以L1Admin身份输入,我只能看到列表页面,而菜单已经正确创建了。在列表页面中,我使用HTML语言进行列表编写。那么如何根据已登录用户的权限隐藏编辑/详细信息链接。

 <div style="float: left">
        <table width="50%">
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th>
                </th>
            </tr>
            @foreach (var item in Model)
            {
                <tr>
                    <td style="width:30%;">
                        @Html.DisplayFor(modelItem => item.Name)
                    </td>
                    <td style="width:20%;">
// I need to hide EDIT/DELETE based on the permission setting of Current logged in user.
                        @Html.ActionLink("Edit", "Edit", new { id = item.ID }) | 
                        <a href="Server/@item.ID">Details</a> |
                        @Html.ActionLink("Delete", "Delete", new { id = item.ID })
                    </td>
                </tr>
            }
        </table>
    </div>

提前感谢。

编辑

我将权限细节存储在数据库中。


你好VeekKayBee,我有类似的需求,你解决了吗? - gs11111
@gs11111 是的,我从下面的答案中得到了一个解决方案。只需查看所有的解决方案,你就会有一些想法。我不能建议一个正确的答案。所有的答案都给了我实现这个的输入。 - kbvishnu
我已经查看了解决方案,但是我无法弄清如何应用它。您能否概述一下您所应用的解决方案?这将是一个很大的帮助。 - gs11111
@gs11111 很抱歉我现在才看到你的评论 :( 我创建了一个包含权限子类的用户对象。根据页面中每个角色指定的访问权限,我只需创建一个Html.helper函数返回true或false。该函数将评估权限设置并切换控件的可见性。 - kbvishnu
5个回答

48
例如,您可以像这样完成它:
@if (ViewContext.HttpContext.User.IsInRole("Your role"))
{
    // Do something here
}

16

方案一 - 假设你正在使用asp.net会员资格。

@if (Roles.IsUserInRole("Administrator"))
{ 
  //show link 
}
else
{
  //hide link/button
}

选项2 - 如果您要自己创建AuthCookie并稍后将HttpContext.Current.User设置为Global.asax.cs文件的Application_PostAuthenticateRequest方法中的新GenericPrinciple(从authcookie的userdata中获取用户角色),则可以在userData中指定角色 - 实现的具体细节可以参考搜索引擎。

这应该会在以后起作用。

System.Web.HttpContext.Current.User.IsInRole("RoleName");

但是如果我使用来自我的数据库的自定义角色,那么怎么办? - kbvishnu
我已更新我的答案。如果您需要更多细节,请告诉我。我鼓励您谷歌这些术语并找到有关身份验证的见解,因为这是一个非常敏感的主题,您应该了解。 - RollerCosta

6
由于权限细节存储在数据库中,您可以通过以下方式检查权限:
选项1 创建授权操作链接扩展。请创建自定义的html授权ActionLink并按以下方式调用。示例请参见此处
 <ul id="menu">              
    <li><%: Html.ActionLink("Home", "Index", "Home")%></li>
    <li><%: Html.ActionLink("About", "About", "Home")%></li>

    // Next line What you are looking for
    <li><%: Html.ActionLinkAuthorized("The Privilege Zone", "ThePrivilegeZone", "Home", true)%></li>
</ul>

注意:为了更好的安全性,您需要创建一个自定义操作过滤器来检查所有请求是否已经授权。
选项2:创建一个静态函数,在操作链接之前进行检查。
public static bool IsUserInRole(string rolenamefrom session)
{
    // Check the user have the privilege then return true/false
}

@if (IsUserInRole("Administrator"))
{ //show link }
else
{//hide link/button}

5
制作一个自定义的帮助扩展,像下面这样,其中CustomMethodForRetrievingUserFlag()返回用户权限,CustomMethodForRetrievingFlags返回允许的操作权限。祝好运。
在视图中使用:@Url.CustomUrl("Home", "Index")
[Flags]
public enum AuthorizeFlags
{
    Administrator = 1,
    L1 = 2,
    L2 = 4
}

public static class UrlHelperExtensions
{
    public static MvcHtmlString CustomUrl(this UrlHelper urlHelper, string controllerName, string actionName, object routeValues = null)
    {
        var actionFlag = CustomMethodForRetrievingFlags(actionName);
        var userFlag = CustomMethodForRetrievingUserFlag();

        if ((actionFlag & userFlag) == userFlag)
        {
            return new MvcHtmlString(urlHelper.Action(actionName, controllerName, routeValues));
        }

        return new MvcHtmlString(String.Empty);
    }

    private static AuthorizeFlags CustomMethodForRetrievingUserFlag()
    {
        return AuthorizeFlags.L2;
    }

    private static AuthorizeFlags CustomMethodForRetrievingFlags(string actionName)
    {
        return (AuthorizeFlags.Administrator | AuthorizeFlags.L1); // test stub
    }
}

但是在提交按钮的情况下,我该如何隐藏或禁用它呢?L2管理员可以保存数据,但只有L1管理员可以授权。因此,L1管理员和L2管理员都可以看到这两个按钮,但根据其权限,它将被隐藏或禁用。 - kbvishnu
如果您不打算提交任何数据,请在表单中添加“#”操作。 - Alex Yaroshevich
创建一个自定义扩展,类似于Html.BeginForm,可以返回表单元素或不返回任何内容。 - Alex Yaroshevich

3
@if (User.Identity.IsAuthenticated)// check whether the user is authenticated or not
    {
        if (User.IsInRole("HR"))//Check wether the user is in that role
        {
            //Contents to be displayed for that Role!
            //some sample content which will be displayed to the user of a Role HR
            <div>
                <h5><strong>HR Approval</strong></h5>
            </div>
            <div>
                <button type="button" name="btnApprove" id="btnApprove">Approve</button>
                <button type="button" name="btnReject" id="btnReject">Reject</button>
            </div>
            <br />
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接