That's kinda vague so here's the meaty stuff:
I have seen authentication systems that do one of the following
have a separate role table for each roles, and a separate permissions table, all users in one table
have a separate table for administrators
there's a lot that I have missed, I know. But what I'm trying to really ask is:
How should I design my database in a website that I have a lot of kinds of users and each with different access?
How will I make it so that my script is flexible enough if I decide to add another type of user with another type of permissions?
I currently have a User class and am planning to make my Administrator class which extends that User class. Or is that a bit of an overkill when I can have them all in a single class and just assign necessary permissions?
you can have tables -
user (user_id, name ...)
permission (perm_id, name, desc)
role (role_id, title)
user_role (user_id, role_id)
user_permission (user_id, perm_id)
role_permission (role_id, perm_id)
This way you can have as many roles in the system as you require, and you have both role level permissions, user level permissions.
you can add an additional level of abstraction. basically you add a table in your database to manage user groups, and assign group permissions to those groups. different users can have multiple groups.
this way you can quickly change permissions to a predefined set of rules, without needing to change every user separately. you can also change the permissions for a group of users at once
I think you need to think about several concepts here. The first would be an access control list (ACL) and then second would be authentication.
In an ACL, you define resources, which are objects that you want to restrict access to and roles, which are objects that may request access to a resource.
The way I implement my ACL, is using Zend_Acl. I have a table called user_roles
user_roles('user_role_id', 'name', 'permissions', 'parent_role_id')`
I also have a table called user_role_maps that maps a user's ID to a user role ID. (You could just have this as a column on the user table, but that just depends on how you feel about normalisation ;-) .) I can then construct my Zend_Acl object from this table and then, when a user is authenticated, I can determine which resources they have permission to and what actions they can perform on a resource. (A resource implements Zend_Acl_Resource_Interface so it is identifiable by Zend_Acl as a resource.
As for authentication, this is a simpler concept (in my opinion), you've probably already figured out some form of token matching authentication system yourself. The crucial aspect is using the authenticated user's ID to determine their role. The Zend Framework also provides a package for this in Zend_Auth.
I've used a lot of Zend Framework recommendations here, the reason for this is that their packages have very few dependencies on other packages, making it quite simple to plug components in. I'm sure other frameworks provide ACL packages that you could use, or roll out your own if you have the time and understanding.
Good Luck.
Related
I'm creating a Symfony2 website that has users and each user can have multiple permissions like this:
User1: manage users , manage sales , manage repository
User2: manage repository
user3: manage sales , manage repository
...
for such a system what is the correct permission system to use?
Roles or ACLs or voters or something else?
Thanks
Roles
Roles are OK if you want to grant "general" permissions.
For example, if you need user to be able to manage all or users, then you can create a role for it, for example ROLE_USER_MANAGER. Or if you want to grant him rights to manage sales, you can grant him ROLE_SALES_MANAGER role.
So basically, use Roles when you have limited number of permissions to some entities generally.
You can use them for other stuff by granting roles that contain entity names and ids for example, ROLE_MANAGER_REPOSITORY_23 and then using custom voters you can know that users with that role can manage repository with id 23. Even though this approach can work, I personally don't like it.
ACL
If you have a lot of dynamic permission granting, especially towards individual models, then ACL is the way to go. It is usually a bit less performant, as it needs to fetch more data from the data store, but is a lot more suitable for this purpose.
With Symfony2 ACL, it's incredibly easy to grant and check permissions, and even to allow individual users to grant permissions to each other.
Furthermore, introduction part of Symfony ACL docs shows you both of these approaches and also point out some ups/downs for each.
I'm having a difficult time grasping the code behind role-based access control (RBAC). I'm trying to use a "bundle" with the Laravel framework but it only seems to be complicating things more.
What I need for my specific application is three roles. The first and most basic role is just to allow users to be able log into my application, manage their account, and save "favorites" and "deals". The second role I need is to allow store owners to be able to log in and create accounts and deals. The third role is basically an admin role so I can go in and remove unwanted content if need be.
Would there be any anticipated problems with just simply adding an int field to the user table called something like "role"? If a user's role is 0, then they have basic privileges and can't access the admin and owner area of the site; a 1 would indicate the user has an owner role, etc. I would simply check the user's role every time a request was made.
Would this be a reasonable, secure solution, or could I potentially run into problems using this approach?
Using RBAC would give you more flexibility when it comes to managing access to your application's functionality. Each user can be assigned with multiple roles, tasks and operations; each role can consist of multiple tasks and each tasks can consist of multiple operations.
If your application only demands 3 roles, basic, owner and admin, I think it's fine to just add an indicator in your user table. However, if you need to grant certain users access to certain operations, you would need a new number for every operation you want to differentiate access controls. Hence, using that approach would make it difficult to separate permissions based on functionality.
An alternative solution is to use ACL, which I believe it's easier to implement but probably a bit more difficult to manage. You can learn the difference between ACL and RBAC here.
The context is a educational administration system built on the Zend Framework. We are implementing a RESTful MVC to handle pretty much all data interactions with clients. Relationships between resources are mapped in the database with foreign keys etc.
Example case: a teacher creating a report on a specific student.
We currently have a role-based permissions system that can be tailored to the level of the individual role (using, eg, teacher_5 as the role name). Therefore we can easily restrict access to an already existing report (by generating permissions in the report model that allows edit/put permissions on the report only to the tutor role who created it, say). The problem comes on creation. In order to add a report a user can post to /reports, say, the following data:
{ achievement: "4", performance: "5", student_id: "10" }
The problem is that tutors are only allowed to create new reports on a certain subset of student_ids - those students that they are teaching.
One approach would be to treat this as a validation issue on that field. The issue with this is that we want to protect ourselves from making mistakes, and that is not easy to do with validation (the code would have to know in advance that special validation is expected on certain fields).
The other would be to somehow extend our permissions system to a completely granular one (i.e., there would be a permission for every field in every model), and then extend our current permissions system to responding to paramaterised permissions checks. So if we wanted to know if the current user has permissions to add student_id 10 to a report on creation, we would end up with something like
if ($acl->isAllowed($resource, $role, $action, $field, $value))
where $resource would be a report model, $role would be the teacher teacher_5, $action would be "post", $field would be student_id, and $value would be 10. The acl class would essentially handle a call to the $resource itself.
We are not sure which direction to take, but presumably this is a fairly common issue, so we are wondering what approach other people have taken.
What about having another table containing the student_id's that each teacher tutors. Then you can easily check if the teacher is allowed to do the insertion. Another benefit from that solution would be the ability to extract statistics about the whole class, like average grades, attendance etc
Given a website site has different web pages that can only be accessed by different group of users. Say guest users can only access welcome page/search page, while, administrator users can access pages that update the DB, etc.
I have little experience on this field and would like to adopt some best practice with clean/simple/secure implementation.
If possible, I would like to see some concrete examples/tutorials, even a book resource.
Thank you for your helps
I have found that many applications available online (Wordpress, Joomla, and many other), are very poorly organized in this field (poorer than what I do, in any case).
Take a look at how it's done for MVC frameworks like Zend Framework, CakePHP, Symfony. MVC is mostly used for bigger projects that tend to be much more organized, so I am betting that they have worked a lot on authentication too.
In 2 words, for this to work properly, all your page generation classes (I advise the use of OOP) must be derived from a parent class, which will hold access control methods. Or you could have a class with static functions for access control. Before any action, simply call these functions to check whether the user has access to this functionality. Functionality can be grouped into Classes, with many Methods (in MVC - Controllers and Actions). You can store access information in the database as follows: groupID, Class, Method, Permission, where permission could be a boolean Grant or Deny. To promote speed, extract all user's permissions at first query, store it in an array or object, so as not to generate a query for each permission verification in the user request, but parse the saved data instead..
Each user can have a role or roles in your application / website. Imagine you have an application where some people can edit users and others can insert tasks while others can solve the tasks. Create three roles: user managers, task assigners and task solvers.
Then give users their roles.
Some people call roles groups. You group people to give them permissions. I prefer calling it role because user acts as HR manager or website publisher etc.
This is just a simple example, it's always based on requirements you have. There can be team-based permissions, department-based permissions etc.
http://en.wikipedia.org/wiki/Role-based_access_control
Personally, I have an application broken down to modules. Each module has objects and these objects have actions. Example: user.department.list = in module user, there's an object department and action list (departments). When you create role or group, assign these permissions to that role (group) and users. For role User managers, there're permissions user.user.list, user.user.edit, user.department.list, user.department.edit. After you authenticate a user (to know who's he) load roles he's assigned to. Each page (controller) or each method can check user's permissions - is this user permitted to list departments?
I'am working on a PHP + MySQL Social Networking application, now i need to setup different access control (read,create,edit,delete) for global (all items) and/or self items (item which created by themselves) for each module to group or specific user.
Does anyone has suggestions in doing this (table structures, etc)?
okay here i provide more detail, currently i have a tbl_module, tbl_user, and tbl_user_role. Each user and role can have different access to specific module.
read
update
create
delete
and devided by global access or self only (own account or records created by themselves).
and my current approach: i create another table to hold the access detail:
acl_uid
mod_id (fk module uid)
target_id (fk user uid or role uid)
acl_type (user/role to identify the target id reference)
acl_read
acl_update
acl_create
acl_delete
acl_read, acl_update, acl_create, acl_delete value ranges:
0 deny
1 allow
2 refer to lower priority check (if user has value 2 then refer to role)
3 self only
i believe that theres more efficient way to solve this, or may an improvement to my current approach.
thanks for your responses.
That's a pretty broad question, so you're likely to only get very broad answers.
Most CMS systems have a table that lists the types of content that can be produced on the system.
Another table describes how each type of content is displayed (on the front page, on individual blog pages, etc).
Another table gives each user one or more "user types" or "groups" such as admin, unregistered, moderator, etc.
A last table is an access table of sorts - it shows what each group has power to do, including the types of content it can create, edit, publish, etc.
I recommend you spend a little time studying the database schemas of other CMS software, such as Slashcode, Drupal, or one of the other millions of CMS systems.
-Adam
It is in fact a very broad question. Assuming you have a clear separation of application tiers (eg, using MVC), then this is the sort of stuff going in the business layer.
Taking your direct requirements, it could be fairly simple. In your users table, have a hasEdit, hasView, etc. For each item, attach a userid to it representing the creator. In the business layer, the rule is they have edit permission if they are the creator, or they have hasEdit = true.
Taking it up a notch, if you have different types, and the hasEdit permission is per-type, you need another entity for that.
userPermission
userPermissionId
userId (FK)
typeId (FK)
hasEdit (boolean)
hasView
etc..
To find out if they have permission to edit, you check if either they're the owner, or look up that items type and the current user in the userPermission table, and check hasEdit. You could make additional rules, like putting a global hasEdit in the user table. Or representing global hasEdit by an entry in userPermissionId with a NULL typeId.
This can get way more complex, using roles and variable numbers of permissions.. it all comes down to your requirements. You need to carefully spec out your business requirements (come up with a bunch of use cases), and then you can design from there. As is, there's really not enough information to come up with anymore than I've outlined here (and even this is probably not exactly what you need).
I like to use a kind of firewall rules approach or similarly a mysql tables rules approach: you can grant users or groups of users certain rights on certain objects or groups of objects. Make each rule be a row in your rules table. When you need to do an action like edit, you can inner join on your rules table for the current user, current user's group, the boolean edit column and the object id or object group. If you get any rows back then the permission is granted.
There are quite a few ways of designing security, and I've liked quite a few for different situations. There's UNIX-style user-group-other. I happen to like PmWiki's security model.
I developed a website which used user-role-permissions structure similar to Apache. With that website, I used a template system that used a header include file and a footer include file to wrap the page contents with the "standard stuff". A page with restricted content could set a variable to the required permission, that the header script looks for, and if set, calls an auth function that checks the user belongs to a role that permission.
The nice thing about using the user-role-permissions model is if most of your users fall into neat categories of authorization, setting the authorization for a user is a simple matter of adding the right role to that user. The permissions are linked to roles, not users directly, so you can adjust the permissions of entire classes of users easily.