Reputation: 307
I am writing a multi-user code. Have different levels of access for example admin and user. Admin has more privileges than a normal user and vice versa. Using Codeigniter as the framework but moving to Laravel framework for the next project. Now if I have a function for example,
function editSomething()
{
$book_id = new Book();
$id = $this->input-post('id');
// and then simply,
if($book->where('id', $id)->update($data))
}
Clearly, there is no validation on who (user) is POSTing the id. It can be anything like http://localhost/?foo=bar and bam the controller will execute.
I am trying to understand that in a such environment how can I secure my functions from unauthorized access, does the framework gives me any protections or instructions to do so so this is going to be my logic to check the owner of the item and then update accordingly. Does this means that for all the records in the db, I should be saving owner_id (or something) to identify the owner of the record?
I am having hard time understand the concept here so any guidance would be appreciated.
Thanks.
Upvotes: 0
Views: 1469
Reputation: 60413
Besides adding owner's id in each table, is that also being done differently? I think this is not framework specific but a concept to grasp in general.
I think this depends heavily on the relationship of the user and its table to other entities and their backing tables. In some instances it makes sense to add a user_id to a table to denote ownership. That however can be limiting... What if you want to secure things that are not actual database backed entities in the system (like controllers or actions)? If you are looking for something robust I would recommend using a set of generic ACL tables much like @bencohenbaritone except for the fact that he left out the Resource table:
This schema is pretty basic as it doesn't allow for nested or grouped roles but it gives you the idea. Now based on this one would most likely create a service that takes resource, permission and a user or role and evaluates whether or not the operation can be performed. It might look something like this:
$acl = $dic->getService('acl');
if ($acl->isAllowed($userOrRole, $resource, $perm)) {
// do stuff!
} else {
throw new Exception('You do not have access to perform this operation.', 403);
}
You could implement this is a request filter, in a controller or somewhere else altogether. That really depends on the type of resource and your business rules.
Typically you would apply the concept of an ACL/RBAC to this problem. Things in your system that need to be secured with different levels of access would be Resources. Users would then have one or more Roles. Each Role would have a set of Permissions for a given Resource.
How you store and check this information is more or less up to you but it's generally not built in to frameworks by default beyond basic authentication and sometimes basic filesystem like permissions (often combined with authentication).
You might want to look at Zend Framework and Zend Framework 2 for examples of an ACL library implementation.
Zend_Acl
Zend\Permissions\Acl
Zend\Permissions\Rbac
With any of those you would still need to work out where and how you want to check against the ACL and what you want to make Resources.
Upvotes: 2
Reputation: 3101
For the authentication I use Ion Auth and the whole navigation, submenus, etc, I put in a separate config file. It looks like:
$config["nav"]["ajax_table/show_sport"] =
array(
"permission" => "100",
"subnav" => "FALSE",
"label" => lang("show_sport"),
"location" => "c=ajax_table&m=show_sport",
"parent_id" => "ajax_table"
);
The important part for you is: permission. I have extended the table «groups» with a column called permission, where I put for each role a value in. In my example 100 is a normal user, 1000 an admin.
In my basecontroler I check every request:
$this->navigation = $this->config->item("nav");
$role = $this->ion_auth_model->get_role();
if ($this->role < $this->navigation[$this->router->class . "/" . $this->router->method]["permission"]){
redirect("your/url/here", "refresh");
}
That's it.
Upvotes: 0
Reputation: 486
It depends on how tightly you want to control access to the resource.
For example, you may want to have one group of users who can update any post, but you might also want to have some users who can only edit their own posts. If you need the latter, then you will want to store an owner column in the table of the resource. This is a good practice in general; even if you don't use it for access control, it's good to be able to audit who created a resource. You can even create audit tables to track when objects are modified and by whom.
In your users table you can map users to roles (for a more sophisticated system, create a separate users_roles pivot), and then whatever auth/login/session management system you're using (this is typically provided by the framework) should have a method to check the current user's role. You can then assign permissions to each role. A sample schema might be something like:
|Users | |User_Role | |Permissions |
------------ -------------- |Roles | ----------------
|id | ==== |user_id | ------- |id |
|... | |role_id | ===== |id |===|role_id |
---------- ------------ |name | |resource |
------ |action |
--------------
You can then add a conditional to check whether the logged in user has the correct permissions in the controller actions you need to protect.
Some frameworks, including Laravel, allow you to apply filters to routes or controllers. See here: http://laravel.com/docs/4.2/routing#route-filters. This helps you avoid copying the same authentication logic into multiple controller methods.
Upvotes: 2
Reputation: 6381
Laravel has this kind of authentication built in, you would just have to add a method like isAdmin()
to your User
object and use it like this:
<?php
function editSomething()
{
if (!Auth::user()->isAdmin())
App::abort(403);
...
The concept would be similar for CodeIgniter. I'm not as familiar with CodeIgniter, but as far as I can tell you'd probably need a 3rd party library like this one:
Upvotes: 0