Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom page access security with MVC 4

I have a system where all pages (views) and all controls (buttons, links, menu itens ...) have security roles applied to them.

So I have an admin interface where all pages and controls are registered. And each user has a set of individual permissions.

So, for example:

I have a View EditCar, with 3 buttons: "New", "Delete" and "Back".

So the user X have permission to see View EditCar, and only the button "Back"

So each new view must be registered, and the users associated with. There is no roles, because each user is 100% configurable.

So, I have a FilterAttribute:

public class CustomAuthorize : FilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {

            var userPermissions = repository.GetAll().Where(x => x.Name.Equals(User.Identity.Name);                

            //   if (!userPermissions.Pages.Any(x => x.NamePage.Contains(???))))               
        }
        else
        {
            filterContext.Result = new HttpUnauthorizedResult();          
        }
    }
}

So my question is : - What should I keep in database to identify each View(Action) ? Maybe 3 values? Area-Controller-Action?

Is it the best option? Any other idea about that solution?

Thanks

like image 282
Paul Avatar asked Oct 18 '13 19:10

Paul


1 Answers

I have same scenario in my web-application and it is working in the following way:

we have in database:

Permission contains View, Add, Edit, Delete

Feature contains all the feature which can be set over role

FeaturePermission bind the feature with permission like which feature has what permisssion

UserRole has the role of a user

RoleFeaturePermission shows that which role has what permission to allowed

Now in code I do when a user authenticate I generate the list of permission assigned to it with features then I defined an Enum like:

public enum FeatureValue
{
    Custom = 1,
    Schedule = 2,
    Export=3          
}

public enum PermissionValue
{
    View = 1,
    Add = 2,
    Edit = 3,
    Delete = 4
}

and the UserPermission static class to get authorization:

  public static bool VerifyPermission(FeatureValue feature, PermissionValue permission, int id) {
      return getFeaturePermissionsForReport(feature, permission, id);
  }


  private static bool getFeaturePermissionsForReport(FeatureValue feature, PermissionValue permission, int id) {
      SessionHelper sessionHelper = new SessionHelper(null);
      UserModel userModel = sessionHelper .getUser()//get user from session.

      if (userModel != null && userModel.IsAuthorized == false) return false;

      UserProfile userProfile = sessionHelper.Get<UserProfile> ();

      if (userProfile != null && userProfile.AssignedRoleList != null) {
          List<Core.Entities.FeaturePermission> featurePermission = userProfile.AssignedRoleList.SelectMany(b => b.RoleFeaturePermission).ToList();


          if (featurePermission != null) {
              if (featurePermission.Count(f = > f.Feature.Id == (int) feature && f.Permission.Id == (int) permission) > 0) {
                  bool isAllowed= false;

                  int featurePermissionId = featurePermission.Where(f = > f.Feature.Id == (int) feature && f.Permission.Id == (int) permission).Select(i = > i.Id).FirstOrDefault();
                  isAllowed = (reports.Count(r = > (r.FeaturePermissionId == featurePermissionId && r.Id == id)) > 0) ? true : false;

                  return isAllowed;
              }
          }
      }

      return false;
  }

and now one each link, button or action use:

 @if (UserPermission.VerifyPermission(FeatureValue.Custom, PermissionValue.Edit))
 {
    //action  link to edit custom view
 }

and for action custom attribute is:

  [AttributeUsage(AttributeTargets.All,AllowMultiple=true)]
    public class CustomFeaturePermissionAttribute : ActionFilterAttribute
    {
        private FeatureValue[] feature;
        private PermissionValue[] permission;
        private bool excludeParamId;
        /// <summary>
        /// Set values of featurelist and permission list
        /// </summary>
        /// <param name="featureList"></param>
        /// <param name="permissionList"></param>
        public CustomFeaturePermissionAttribute(object featureList,object permissionList, int excludeParamId)
        {
            FeatureList = (FeatureValue[])featureList;
            PermissionList = (PermissionValue[])permissionList;
            ExcludeParamId = excludeParamId;
        }
        public FeatureValue[] FeatureList
        {
            get
            {
                return feature;
            }
            set
            {
                feature = value;
            }
        }

        public bool ExcludeParamId
        {
            get
            {
                return excludeParamId;
            }
            set
            {
                excludeParamId = value;
            }
        }

        public PermissionValue[] PermissionList
        {
            get
            {
                return permission;
            }
            set
            {
                permission = value;
            }
        }
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);

            bool isAccessAllowed = false;
            FeatureValue feature;
            PermissionValue permission;

            for (int i = 0; i < FeatureList.Count(); i++)
            {
                feature = FeatureList[i];
                permission = PermissionList[i];

                    isAccessAllowed = UserPermission.VerifyPermission(feature, permission, Convert.ToInt16(ExcludeParamId));

                if (isAccessAllowed)
                    break;
            }

            if (!isAccessAllowed)
            {
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { action = "UnauthorizedAccess", controller = "Security" }));
            } 

        }
    }

and on actions allow role having view permission over Custom and Export:

[CustomFeaturePermission(new FeatureValue[] { FeatureValue.Custom, FeatureValue.Export }, new PermissionValue[] { PermissionValue.View, PermissionValue.View},pageId)]
public ActionResult Custom()
{
   //action body
}
like image 78
Zaheer Ahmed Avatar answered Oct 06 '22 01:10

Zaheer Ahmed