views:

149

answers:

2

I am developing a site that needs an access permissioning scheme. I am uncertain how I want to structure the scheme, and I am having a hard time finding good resources on determining not just how to implement a permission scheme, but how to plan what the scheme should be capable of doing.

I have lots of questions and not a lot of solid information. And I can't formulate the pros and cons of the available answers.

  • Should it be role based and if users have roles?
  • Should it be group based?
    • Should groups be able to be members of Groups, as in AD?
    • Or should only users be able to be members of groups?
  • How should I handle permission defaults?
    • Should the be set based off the tool that creates the page?
    • Should the creating user set the permissions on page creation?
  • Should users be able to create their own groups?

What is your experience in designing permission schemes? I am pretty green in this, and any good resources, books, blogs, etc., would be really helpful.

A: 

I have been impressed with the flexibility and power of KnowledgeTree's permission system.

It's roughly organized as follows: Business Units -> Groups (and subgroups) -> Roles -> User

KT is a document management system but all permissions are assigned at the directory level, not on assets themselves. Each asset and sub-directory inherits the permissions from its parent.

This allows you to set pretty broad permissions on a group basis and really narrow it down by setting more explicit permissions on a role. Users are then assigned to roles on an as-needed basis; user A might be assigned to an Editor role for directory X but not to Y. Those permissions would layer on top of whatever group user A is already in.

My one complaint is that there's no real way to define specific permissions to a user directly. If I want user B to have certain access to all directories, I either have to add them to a group or assign them to a role (which in turn must be created or assigned to directories).

TYPOlight webCMS kind of rectifies this problem although it's not nearly as robust. Each user in the CMS may use their group permissions (only), extend their group permissions with individual permissions, or use individual permissions (only).

Mark Hurd
+1  A: 

These ideas may or may not be any good for you, but I built a web-based, permission driven system, from scratch (I needed low level control to integrate with another system), like so:

  • Users or groups may have permissions
  • A user's effective permission set is the superset of all Allows and Denys for the user and the groups that user is a member of
  • Denys override Allows
  • User level permissions override any group settings (allowing you to priviledge admins, supervisors etc)
  • A user's effective permission set is stored in session when they login and then permissions are tested via a permissions manager (using bitwise ops)
  • Each permission area has it's own bit mask, and these are stored in the db, allowing you to auto generate a permissions utility class as part of your build process. The utility class looked like so:

    public static class Area1
    {
        public static int AreaId { get { return 1; } }
        public static int Permission1 { get { return 1; } }
        public static int Permission2 { get { return 2; } }
        public static int Permission3 { get { return 4; } }
    }
    public static class Area2
    {
        public static int AreaId { get { return 2; } }
        public static int Permission1 { get { return 1; } }
        public static int Permission2 { get { return 2; } }
        public static int Permission3 { get { return 4; } }
        public static int Permission4 { get { return 8; } }
        public static int Permission5 { get { return 16; } }
    }
    

    etc ...

  • Then you can define a permissions base page:

    public class PermissionsPage: BasePage
    {
        int _permissionAreaId;
        int _permissionValue;
        string _page;
    
    
    public PermissionsPage(int permissionAreaId, int permissionValue)
        : base()  
    {
        Init += new EventHandler(PermissionsPage_Init);
        _permissionTypeId = permissionTypeId;
        _permissionValue = permissionValue;
    }
    
    
    void PermissionsPage_Init(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            _page = Request.Url.Segments.Last();
            if (!PermissionsManager.TestPermission(UserWebSession.User, _permissionTypeId, _permissionValue))
            {
                // handle permission denied
            }
            else
            {
                // log page access
            }
        }
    }
    

    }

  • The utility file then allows you to do this kind of thing during development:

    public partial class yourControlledPage : PermissionsPage
    {
         // test permission over an entire page
         public yourControlledPage()
            : base(PermissionDef.Area1.AreaId, PermissionDef.Area1.Permission1)
         {
         }
    }
    
  • or

     // test permission over a specific control
     yourDropDownList.Enabled = PermissionsManager.TestPermission(UserWebSession.User, PermissionDef.Area2.AreaId, PermissionDef.Area2.Permission4);
    

*Where 'Area1' and 'Permission1' for example are replaced with meaningful names.. obviously!

Then again, there may well be third party libraries you can plug in quite nicely and do all you need...

flesh