How to store Role Based Access rights in web application?

Currently working on a web based CRM type system that deals with various Modules such as Companies, Contacts, Projects, Sub Projects, etc. A typical CRM type system (asp.net web form, C#, SQL Server backend). We plan to implement role based security so that basically a user can have one or more roles.

Roles would be broken down by first the module type such as:

-Company

-Contact

And then by the actions for that module for instance each module would end up with a table such as this:

Role1 Example:

    Module   Create  Edit        Delete   View
    Company   Yes    Owner Only    No     Yes
    Contact   Yes    Yes           Yes    Yes

In the above case Role1 has two module types (Company, and Contact). For company, the person assigned to this role can create companies, can view companies, can only edit records he/she created and cannot delete. For this same role for the module contact this user can create contacts, edit contacts, delete contacts, and view contacts (full rights basically).

I am wondering is it best upon coming into the system to session the user’s role with something like a:

List<Role> roles;

Where the Role class would have some sort of List<Module> modules; (can contain Company, Contact, etc.).? Something to the effect of:

class Role{
string name;
string desc;
List<Module> modules;
}

And the module action class would have a set of actions (Create, Edit, Delete, etc.) for each module:

class ModuleActions{
List<Action> actions;
}

And the action has a value of whether the user can perform the right:

class Action{
string right;
}

Just a rough idea, I know the action could be an enum and the ModuleAction can probably be eliminated with a List<x, y>. My main question is what would be the best way to store this information in this type of application: Should I store it in the User Session state (I have a session class where I manage things related to the user). I generally load this during the initial loading of the application (global.asax). I can simply tack onto this session.

Or should this be loaded at the page load event of each module (page load of company etc..). I eventually need to be able to hide / unhide various buttons / divs based on the user’s role and that is what got me thinking to load this via session.

Any examples or points would be great.

1

Well, I think your design is fine I would only recommend you only a simple thing on how to store the roles. I have here a system that has almost the same concepts. It is not based on roles as per the name.

So I have a user session object with objects of type Map that store the permissions that the user has. And this Map objects is filled on demmand It will be something like:

public class UserSession {
    HashMap<Application, Action> map;

    public boolean hasPermissionApp( Application app ){
        if ( !map.containsKey(app) ){
            //check if the user has the permission on the DB or whatever you store it
            //if it has add it to the map with the action that 
            //it came along and return true
            //if it hasn't return false
        }
        return true;
    }

    public boolean hasPermissionAction( Application app, Action act ) {
        if ( hasPermissionApp(app) ){
            if ( !map.get(app).containsKey(act) ){
                //check if the user has permission to that action of the app
                //if it has add to the map and return true
                //if not return false
            }
        }
        return false;
    }
}

That way you load the user permisson and store it by demmand and don’t overload the session object with the full set of permissions that the user has.

EDIT

As OP asked on the comments:

  • Do you fill this hashmap at every sort of click event that requires role permissions?

The answer is almost this. When the user logs in an application the user session object is empty, so for the Application that He is logging in I would check if He has access and if so, I add it to the map with the first Action that was called by that Application lets say ‘View’. And with this Action the user can see the search form.

Here you can have two approach. Which is what you asked!

  • Check permissions when the user fire the events like with this ‘View’ Action it can see the entire form with the buttons search, add, cancel (or whatever others) But the permission will be checked only when the user press the button. Then it if have you add to the map or send him a message saying that it does not have that permission.

  • Check the permission when rendering the actions. You only show the buttons on the form if the user has that appropriate Action associated to it. So lets say you are using a component library like Richfaces it would be like this:

<a4j:commandButton rendered="#{userSessionObject.hasPermissionAction('appBla','search')}" ..... />

And since this is created on the construction of the page the map would be filled on every check permission that is made on the page or other resources.

And on my application i choose for the second approach, because I don’t think that make sense to show a button to a user that does not have the access to it.

Edit 2

A thing that maybe is usefull is that I associate a thread timing (configurable time) to the user session that clean up the maps on the userSessionObject, so if some administrator change permissions to that user at some point it will have his permissions updated automatically, not exactly at prompt but this was a acceptable requirement to this particular system.

6

I used to work on a system with fixed number of tables/directories (different from yours), so I didn’t use role-base security schema like the one of yours (or of file system, or of SQL DB). I used linear access level. At high level, the thing is similar though, especially with your question.

Nevertheless, wherever and however you store Access Right on the client side, there is no guarantee that it is an accurate reflection of what is on the source (the DB).

  1. Load the access right when the user logs in. Storing access right in a session object is fine.
  2. Validate each action on the logic layer at the backend
  3. Extra: when an action is not completed, the backend will send the feedback about change in access right
  4. Extra Option1: when feedback is received, the backend can also send another chunk to encode new access rights
  5. Extra Option2: when the feedback is received, the front-end suggests the user to re-login

There should be very little overhead associated with getting the user permissions on page load, so do that. Don’t use the session to store much of anything. This will allow permissions to be dynamically changed by admins (so that the user won’t have to login again).

Rather than develop a detailed role infrastructure, why not consider something simpler like assigning permission tags to a user — e.g. company:create, company:edit, etc. These can be interpreted exactly as your current infrastructure would; however, this will permit some additional flexibility with allowing permissions to be assigned to more discrete actions (e.g. not just the CRUD operations).

Lastly, whatever permissions are granted in the client must also be verified on the server when the user submits his action. We can’t simply trust the client. So whether on the client or on the server you’ll check a user’s permission tags and do the right thing. On the client side this might mean changing the interface. On the server side this might mean rejecting a transaction where it appears the user somehow circumvented our permissions (e.g. attempted to create a company where this was disallowed).

2

I think it would be best to store a List<Action> in the session. Resolve this list based on the roles the user has at the beginning of the session.

Unless permissions change often, it is enough that the user permissions are updated on each login.

On a sidenote, I would not design it so that Role has a List<Module> but instead a List<Action>.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật