0

I am currently working on a C# MVC project. I used CustomAuthorizationAttribute to authorize every user in my project.

I have 3 Roles : Super Admin, Admin and User

While creating a new user there is an option for adding the corresponding Role, and it can be edited (The person with 'User' Role can not add or edit users).

To set up this authentication I created two tables, 'PermissionFunction' and 'Permission' respectively. The Table details is given below :

PermissionFunction:

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

Permission:

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

PermFunc_ID and Perm_ID are Primary key for the tables respectively. PermFunc_Name is the name referring each action in all controllers. Permission Table contains Foreign Key for both Role and PermissionFunction tables.

For reference here is my Role table :

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

For authentication I added a class CustomAuthorizationAttribute and added authorization attribute to every controller action.

For example consider my PermissionFunction table vales as below:

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

and my HomeController :

public class UserController : Controller
{

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

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

}

and the CustomAuthorizationAttribute class :

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");
            }
        }
    }

}

This is working fine.


My Question

This is my Index 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>

When CreateButton clicks a modal popup comes for adding details and create a new user.


Is there any way I could hide the create new button if the user has no access to create a new user.? ( ie: If the userCreate is not in the PermissionFunction Table).

2 Answers2

0

You can check permissions and add button to the page if needed. You already know the way to get permission information, so you can store some information in ViewData or ViewBag and check if create button should be there. The information can be just a simple boolean. It will be something like this

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

where CanCreate you can set from your controller.

Ruben Vardanyan
  • 1,298
  • 9
  • 19
0

I would rather suggest you take idea from this thread

However the solution is not very elegant, you could create your own action link like

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

I think you could even get rid of the last parameter and automatically check on connected user and rights required on the action you are calling to chose to display it or not.

If you really need specific html then I suggest the solution in this thread It is easier if you want to handle multiple access rights on one page. Indeed Viewbags will start to be a pain if you have many of them to manage.

Hope this helps

regards

Edit : for implemention the authorizeActionLink I found this

Nerevar
  • 303
  • 1
  • 9