Razor视图中的自定义授权

时间:2017-09-28 07:53:55

标签: c# asp.net-mvc razor role-base-authorization

我目前正在开发一个C#MVC项目。我使用CustomAuthorizationAttribute来授权项目中的每个用户。

我有3个角色:超级管理员,管理员和用户

在创建新用户时,可以选择添加相应的角色,并且可以对其进行编辑(具有'用户'角色的人员无法添加或编辑用户)。

要设置此身份验证,我创建了两个表,' PermissionFunction '和' 权限'分别。表详情如下:

PermissionFunction

|---------------------|------------------|
|   PermFunc_ID       |     bigint       |
|---------------------|------------------|
|   PermFunc_Name     |     varchar(50)  |
|---------------------|------------------|

权限

|---------------------|------------------|
|   Perm_ID           |      bigint      |
|---------------------|------------------|
|   Perm_RollID       |      bigint      |
|---------------------|------------------|
|   Perm_PermFuncID   |      bigint      |
|---------------------|------------------|

PermFunc_ID Perm_ID 分别是表的主键。 PermFunc_Name 是引用所有控制器中每个操作的名称。 权限表包含 Role PermissionFunction 表的外键。

此处参考的是我的角色表:

|---------------------|------------------|
|   Rol_ID            |    bigint        |
|---------------------|------------------|
|   Rol_Name          |    varchar(50)   |
|---------------------|------------------|

对于身份验证,我添加了一个类 CustomAuthorizationAttribute ,并为每个控制器操作添加了授权属性。

例如,考虑我的 PermissionFunction 表值,如下所示:

|---------------------|-------------------|
|   PermFunc_ID       |    PermFunc_Name  |
|---------------------|-------------------|
|       1             |    userIndex      |
|---------------------|-------------------|
|       2             |    userCreate     |
|---------------------|-------------------|

和我的 HomeController

public class UserController : Controller
{

    [CustomAuthorization(IdentityRoles = "userIndex")]
    public ActionResult Index()
    {
        return View();
    }

    [CustomAuthorization(IdentityRoles = "userCreate")]
    public ActionResult Create()
    {
        return View();
    }

}

CustomAuthorizationAttribute 类:

public class CustomAuthorizationAttribute : AuthorizeAttribute
{
    private PermissionRepository _permission = new PermissionRepository();
    private PermissionFuncRepository _permissionFun = new PermissionFuncRepository();

    // roles start
    public string IdentityRoles
    {
        get { return _permissionName ?? String.Empty; }
        set { _permissionName = value; }
    }

    private string _permissionName;

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        //do the base class AuthorizeCore first
        if (httpContext.User.Identity.IsAuthenticated)
        {
            string RoleID = FormsAuthentication.Decrypt(httpContext.Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name.Split('|')[1];

            var permisionID = _permissionFun.FindByName(_permissionName);

            if(permisionID != null)
            {
                var permis = _permission.GetPermission().Where(a => a.Perm_PermFuncID == permisionID.PermFunc_ID && a.Perm_RollID.ToString() == RoleID).FirstOrDefault();
                if (permis != null)
                {
                    return true;
                }
            }

        }
        return false;

    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {

        //if the user is not logged in use the deafult HandleUnauthorizedRequest and redirect to the login page
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
        //if the user is logged in but is trying to access a page he/she doesn't have the right for show the access denied page
        else
        {
            // the controller action was invoked with an AJAX request
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new RedirectResult("~/Home/AccessDeniedNew");
            }
            else
            {
                filterContext.Result = new RedirectResult("~/Home/AccessDenied");
            }
        }
    }

}

这很好用。

<小时/> 我的问题

这是我的索引 html:

<button class="btn btn-sm btn-rounded btn-success" type="button" id ="CreateButton" onclick="UserCreate()"> Create New User </button> // create new user

   .....   // code continues

// code for modal popup
<div id="edit-user" class="modal hide fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">


</div>

<script type="text/javascript">

    function UserCreate() {
        var url = "/User/Create/";
            $.get(url, function (data) {
                $('#edit-user').html(data);
                $('#edit-user').modal('show');
           });
    }
</script>

CreateButton 点击模式弹出窗口时,会添加详细信息并创建新用户。

  

如果用户无权创建新用户,我是否可以隐藏创建新按钮? (即:如果 userCreate 不在 PermissionFunction 表中)。

2 个答案:

答案 0 :(得分:0)

如果需要,您可以检查权限并向页面添加按钮。您已经知道获取权限信息的方式,因此您可以在ViewDataViewBag中存储一些信息,并检查是否存在“创建”按钮。信息可以只是一个简单的boolean。它会是这样的

@if(ViewBag.CanCreate)
{
    <button class="btn btn-sm btn-rounded btn-success" type="button" id ="CreateButton" onclick="UserCreate()"> Create New User </button>
}

您可以从控制器设置CanCreate

答案 1 :(得分:0)

我建议你从this thread

中提出想法

然而,解决方案不是很优雅,你可以创建自己的行动链接,如

@html.AuthorizeActionLink("button name","your action/controller name","your security role")

我认为您甚至可以删除最后一个参数,并自动检查您要调用的操作所需的已连接用户和权限。

如果您确实需要特定的HTML,那么我建议this thread中的解决方案 如果要在一个页面上处理多个访问权限,则会更容易。事实上,如果要管理很多Viewbags,它们将开始变得很痛苦。

希望这有帮助

问候

编辑:为实现authorizeActionLink,我找到了this