2

I'm trying to design a small web platform that would host several "applications", with a common user pool. My reflection is now focused on the authorization system.

I define an application as an interface that allows users to perform CRUD and more custom operations on a set of resources. I tend to prefer to model an application as a collection of RESTful webservices to be consumed from various front ends.

I really would like to generalize the authorization system and to make it application agnostic; I'm thinking of implementing it as a webservice, leveraging unstructured document databases.

Assuming that:

  • A users and groups management service is available to the application developer;
  • The scope of any application would be limited to perform CRUD and more custom operations on resources, as stated previously;

My idea is to provide to developers read/write access to a structure like this:

[{
    "Application":"Application1",
    "Ressource":"ResourceType1",
    "id":"123",
    "read":{
        "whitelist_group_ids":[ 2 ],
        "whitelist_user_ids":[ 1 ],
        "blacklist_users_ids":[ 2 ]
    },
    "CustomOperation1":{
        "whitelist_group_ids":[ * ],
        "whitelist_user_ids":[ 1, 2 ],
        "blacklist_users_ids":[ 3 ]
    }
},{
    "Application":"Application1",
    "Ressource":"ResourceType2",
    "id":"13",
    "read":{
        "whitelist_group_ids":[ * ],
        "whitelist_user_ids":[ 1 ],
        "blacklist_users_ids":[ 2 ]
    },
    "CustomOperation2":{
        "whitelist_group_ids":[ 2 ],
        "whitelist_user_ids":[ 1, 2 ],
        "blacklist_users_ids":[ 3 ]
    }
}]

They would then be able to store, check and update their access restrictions on demand;

What would be the flaws of such an approach? Is there any standard strategy to achieve something close to what I described?

2

Look into Apache Shiro. Going with a canned solution is usually a better move than starting from scratch. They have a solution for your problem that, I can attest, is very easy to implement. It can automatically tie into the user's session and provide authentication and authorization on varying levels.

The most powerful portion of our implementation consisted of a hierarchy of groups such that each group would inherit basic authorizations from its parent, and then override, or add to the authorizations. We decided to use true/false for all our permissions so that each permission would boil down to a yes/no answer. We avoided negatives in the names of permissions so that the code would read more cleanly.

To give you an idea, here's some groups and their permissions:

WebUser
     advanced_tools: false
     admin_tools:false
     tree_navigation:true
     enhanced_panel:false
     search_limit_to_25:true
PaidUser
     advanced_tools:true
     tree_nagivation:false
     search_limit_to_25:false
TrialUser
     advanced_tools:true
AdminUser
     tree_navigation:false
     admin_tools:true

An admin user was also a paid user (as stored in the database), so that first it would apply all the web user authorizations, then the paid user values would overwrite, and finally, the admin user would be applied. We also had authorizations that were assigned to individual users, but it remained unused.

In the server-side source code, we would use Shiro to see if a user was authorized to do tree_navigation or admin_tools before including the code. On every call to the server to perform an action, we verified the user was allowed to do what they were doing. The trick was to not trust any session data - we would recheck all authorizations on every server call. If the session expired, or the user wasn't logged in via Shiro, then the permission check would fail and we would protect our data / information.

The fact that this was all in the database meant that admin users could edit or modify the permissions on the fly, and then trigger a cache update for the user module on server-side.

  • I should also add that I implemented a local login, facebook login, twitter login, and google+ login all from the same framework. – Kieveli Dec 20 '13 at 13:11
  • 1
    For what I read, Shiro provides "verb" authorization check, while I look for verb+resource authorization solution. I'm more interested on the architectural flaws of my proposition than an actual implemented solution. The hierarchical group idea is good, but I doubt the inheritance of user types would go further than 3 or 4 levels, so I guess a flat group array would be way easier to implement. Also, we choose nodejs for the implementation, but my question isn't language related. – zrz Dec 20 '13 at 14:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.