I am implementing role based access control using yii framework for the application mentioned in the Agile web application development using yii framework book.I have implemented every thing up to page number 189.
page number 189 says that following method can be used to check whether user is allowed to perform some action or not.
If( Yii::app()->user->checkAccess('createIssue')) {
//perform needed logic }
but this method always return false for users who have been assigned to createIssue operation
following is the database diagram for RBAC
i am linking UserID and role for authassignment table using following command.
$auth=Yii::app()->authManager; $auth->assign('member',1);
As you can see my user table and authassignment table does not have direct relationship.
And i have configured main.php file in configuration folder
These are the all we have done so far and could any body share your knowledge with me if any thing is missing here. Thanks in advance for any help.
Come on, man! Of course there must be a direct relationship between users and assigments. In the following piece of code:
$auth=Yii::app()->authManager; $auth->assign('member',1)
'member' belongs to authiments, and '1' is the id of the user being assigned with that role. "userid", in the "authassigment" table, must point to users table.
Related
I am currently working on a webapplication in Symfony. The application involves many clients which all have their own account to login with. For the user management I use Friends of Symfony User Bundle which I'm more than happy with.
In the application an Admin needs to see the information belonging to all the clients, where a client needs to get restricted to only be able to see his own information.
At this point FOS assigns the role "User" to all the accounts I register. I have considered to only give the client access to information belonging to him by using a query like;
$query = $this->getEntityManager()
->createQuery(
'SELECT c FROM clientsBundle:client c
WHERE c.name LIKE :string'
)->setParameter('string', '%'.$string.'%');
Then give var clientID the value of the clients id, and then get all the information needed according to that value (id).
But to be honest I don't really think this is the best practice.
I was wondering if there is maybe an (easier) option to not only allow the user to access certain pages through security.yml in Symfony, but also make the content in that page user specific.
Any help would be much appreciated.
we're currently working on a large web app that holds accounting information for users. So a similar thing where you only want your user to have access to their own data.
we simply write a number of verifyAccessTo methods that check that the entity that theyre trying to access belongs to their organisation (in our case a school) by assigning a relationship to that entity.
It might look something like this.
public function verifyAccessToTag( School $school, Tag $entry ) {
return $entry->getSchool()->getId() == $school->getId();
}
then when we're listing out data, we'll query specifically for entities relating to that school.
If you have specific area of a site that need particular access, such as admin areas, then in the firewall is the place to do it (security.yml).
If you need to sift and restrict on data, then the way you query and validate access on the specific data is probably the only way.
The whole world of security is a massive one, but heres some resources that might help.
securing services <-- this is really useful for ranked systems
deny access to content
voters
Hope that helps.
You can get the user's id and use that:
$user = $this->container->get('security.context')->getToken()->getUser();
$user->getId();
I'm trying to build my own custom authenticate system on this framework.
I've set up RBAC of Yii. It's working well. It gives me roles.
Later on I've edited the code and now I can get users id, and username also.
But what I want is a bit more complicated.
I don't like this role system of RBAC, because you have fixed roles written inside code.
My idea is a user having usergroup ID. and in database I can manipulate what can does each usergroup.
So for example user loggs in and wants to make new topic,
While authenticate RBAC uses usergroup ID to connect to database and get all data according to this usergroup.
then it creates something like:
$this->setState('create_new_topoic', <info from database);
$this->setState('edit_topic', <info from database);
$this->setState('view_topic'', <info from database);
And then during application in controllers and views I will just use everywhere
if (isset(Yii::app()->user->create_new_topoic) AND (Yii::app()->user->create_new_topoic>0))
{ show 'create new topic button' }
Is this normal practice? I'm interested in how this will react on load of server and MYSQL. I'm overloading my application or such system is ok for server to handle?
What you want is what RBAC exactly can do. In fact, you give a ROLE to user instead of GROUP. Idea is:
Create Your operations (For example create/update)
Create appropriate roles based on your operations (For example Modifier, who can perform create and update)
Assign to users one or more appropriate roles
Wherever/Whenever you can easily check access of your users by their roles
Talking in code:
$rbac=Yii::app()->CAuthManager();
$rbac->createOperation('create','This is a description for this operation')
$rbac->createRole('modifier','This is a description for this role')
$rbac->assign('modifier','USER_ID')
$rbac->checkAccess('modifier')
Please do not limit yourself into RBAC methods provided by Yii. You can do every manipulations in your database and write your own customized methods. (I mean, while you are using rbac, you can customize the way you use it. For example considering groups as roles)
To be more clear, you can read Yii's RBAC document:
Yii's IAuthManager - RBAC
RBAC works just fine. Another method is 1) Assigning User Type to session variable at time of login. 2) Checking User Type in the View. The user table needs a User Type column obviously. I think that approach is fine, and it won't overload your server. Of course it will add a few miliseconds but it is required if you want the same view to display different things based on role.
In your UserIdentity File (/protected/components)
public function authenticate()
{
....
$this->setState('type', $user->type); //Set's Type here
$user->save();
....
}
In Your Views/Controllers
<?php if (Yii::app()->user->type == 'Finance') : ?>
{some code}
<?php else: ?>
{other code}
I have only just started using CakePHP (v2.4.1). I did a fresh install, then I created my database structure and did a cake bake to create all modules, controllers and views. Great! I have also created a login using the Auth component.
I have a users and user_types table along with a user_types_views and a views table as part of the database structure and I want to be able to give access to particular views at usertype level. So I need to reference the database to see if there are any user_types_views records for the usertype logged in, and set the access to authorised for each of these views.
Is this the best way to do it? and are there any hidden little gems in CakePHP which may speed up the process(like the 'cake bake' options).
the CRUD permission setup would do this for you. you'd have to set all the $permKeys to 1 or -1 for access or deny at each function(view) level.
remember to use Crud as the authorize option in the auth properties.
I'm still a newbie in cake.
Suppose you have a table users that has a group_id and a table called groups
Groups:
id role
1 Admin
2 Teacher
3 Student
I'm wondering, what is the difference between for example, using the isAuthorized function to authorize the user to access a certain action and between using the Acl to restrict his access? Is one method more secure than the other?
Also, I was wondering if there is any 'Cakish' way to for example:
- Allow admin to access the edit action
- Allow a student to access the edit action, but restrict him from changing a certain field.
For example, suppose a student is editing the table Users which has the following fields: username, password, group_id . He can edit the password but not the group_id and the username. While the admin can edit both. The way I am implementing this is checking inside the controller, after the user has posted, his group_id , and unsetting the field username and group_id according to his privileges. Is that a proper way of implementing this?
Thank you.
ACL (or Access Control List) is a method of separating the logic of who has access to what from your code. With isAuthorized() you have to manually add code for each possible type of access. Also, ACLs allow (recursive) grouping and matrix-like access (like "allow access to all warriors but not those of race Gremlin"); the documentation of CakePHP is quite extensive.
However, what I personally find lacking in Cake's ACLs is restricting access to specific items. For example, a student may view his results but not from other students; i.e. he may call /results/view/10, /results/view/49 and /results/view/87 but no others. I have not been able to do this with ACLs.
As to editing: it's generally a bad idea to show/post all data, then remove what you deem unnecessary. You're bound to forget a field one day and then you have a bug or vulnerability. I recommend using the Security component to prevent form tampering, then only add those fields to the form that a user may edit, depending on access level.
The CakePHP documentation tells you to manually add the fields you want to save in the POST action of your controller, but that means you have to maintain the list of fields at 2 places: in your view with the form and in the controller. Add code to include/exclude fields based on access level and you have a maintanance headache. With Security anti-tampering users can't add fields manually to manipulate the POST data.
Using Tank Auth for first time along with HMVC. In my application there are 2 type of user one is say student and another is institute.
I created two modules for each user type and separated the tank auth library , both user's registration, login and tables are different from each other.
Now if I try to add any other page which is common to both users like home page, Which library should be used.
I know there must be better solution to handle multiple user problem.
Please let me know where I'm doing wrong. And what should I do to tackle this problem.
You're right, there's a better way to handle this. Duplicating your user / registration system is the wrong way to go.
You'll need to modify TankAuth to include a user type column, and then check for that user type. I'd suggest a new column in the 'users' table for 'user_role':
https://github.com/ilkon/Tank-Auth/blob/master/schema.sql
You could handle the user_type as either an int or enum. I'd lean towards int since enum is harder to change later. You could also add a new table for user_roles but I usually just store these in a config file.
Once the schema is altered, you'll need to add a reference to the new column (along with possible options) in the Tank_Auth code. You'll need to include it in creation, update (data is passed to model from the tank auth controller: controllers/auth.php) and lookup functions. I would add a lookup by user_role as well to the tank_auth model (application / models / tank_auth / users.php):
function get_user_by_role($role)
{
$this->db->where('LOWER(user_role)=', strtolower($role));
$query = $this->db->get($this->table_name);
if ($query->num_rows() == 1) return $query->row();
return NULL;
}
Lastly, you'll want to set the user role to session on login so that you can track the user type (and what content / functionality they have access to).
I've used Tank_Auth myself for several projects.
building on what calvin said, codeigniter does a good job a securing your application, tank auth will verify them, however you need different user levels, this usually falls under permissions. Your job as a developer is to make sure codeigniter does it's security checks via CSRF & XSS( I would suggest you do this in each validaton rule, rather than globally, especially If your admins need to add any tags not allowed suc as "script"). you can see how I personally setup my controllers regardless of my Auth library here...
You need to have a row in your users table called "permissions" which is either a serialized array or json encoded, or you can do a google search on permission bitmasking, which requires an int field