User specific content in Symfony - php

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();

Related

CodeIgniter authentication + user privileges

I'm trying to build an authentication system in my application, but I'm having some problems in deciding which is the best way I could acomplish what I want in CodeIgniter.
The website allows companies to manage their buildings. A company can have many buildings, and many users (when I say users I mean employees from that company).
In this website I would like two have (basically) four general kind of users.
Super Admin: This would be able to add new admins and new companies to the database, and give privileges to the rest of the admins.
Admin: This would be able to do different stuff depending on the assigned privileges.
Company Super User: This user would be created directly when an admin creates a new company. This user would be able to create new users for that company, and since s/he would have total permissions, he would be able to do everything that the other users can do.
Company User: Depending on the privileges assigned by its super user, this user would be able to do and see different data (for example, a simple user would just be able to see information from one of the many company buildings).
So, even though I've seen many authentication libraries out there for CodeIgniter, it would be nice to hear any recommendations about how I could design this "authentication role based" system, and if you particularly recommend a library that could help to accomplish this.
Appreciate!
There Are many libraries that already handle Authentication within Codeigniter, but the one I would recommend is Ion_Auth. It handles user permissions (groups) very well and I've actually done a detailed writeup outlining a good way to handle this situation with Ion_Auth.
I suggest FlexiAuth library which is a re-modified version of ion Auth, and has lot of features already built in, simply out of the box.
I've been developing a role based authentication system for Codeigniter called WolfAuth, here's the repository. It's still early days, but it sort of works. You can add roles, etc and then restrict functions and classes to particular user roles and usernames.
Use CI_aauth. I like this, this is very good from others auth.
https://github.com/kabircse/CodeIgniter-Aauth

Implementing ACL for my PHP application

My RealEstate PHP Application have following user groups,
Admins,
Moderators
Agents
i want to specify following permission to the following users.
Admins - >
Can Create Moderators,
Can Create Agents,
Can Insert Properties,
Can Update Properties,
Can Delete Properties
Hence an Admin will have all the privileges in short an Admin here will be superAdmin
I want to assign limited privileges to the moderator and hence to the agents.
i am confused on how to Create a Database for this and also on how to implement it in my PHP Application.
thank you
It sounds like you are going to need a role-based access control system. Developing one is not
really a trivial task, so as already suggested, finding a framework or ready-made class that does
the job would be a worth while start.
Role Based Access Control
http://www.tonymarston.net/php-mysql/role-based-access-control.html
http://www.sqlrecipes.com/database_design/fine_grained_role_based_access_control_rbac_system-3/
http://www.sitepoint.com/forums/showthread.php?threadid=162027
You should create a table wher you have to define all type of role.
and one table for users
relate different roles to different user Via linking two tables.
and some thing like this ......
The way that I have done this in the past was to create a users table in the database that had an access level (Admin, Moderator, and agents).
Then if you have a menu system, implement a check to see what privileges are needed for what links... Admins will see all links, Moderator will only see links he/she is supposed to, and agents will only see what they are supposed to see.
Also on the pages that you may want to restrict users you will want to check for the users access level. If they pass, they will see the page, if not, they will be redirected or a javascript error will need to pop up.
Something like the access level may do you some good to store it in a cookie as you can cut down your calls to your database.
Hope this helps,
Mike

Creating user roles

I am doing new project in symfony1.4. Now this project requires users to log-in and browse, and as any project of this type requires a way of restricting users based on roles.
I don't want to implement this in obvious way, i.e to have roles attribute for each user and have pre-defined roles and assign these to users. The problem with this is it's not very flexible as more roles get defined later.
I was thinking on the lines of using an EAV model here, (not sure I can do that in symfony). What you guys think, do you have any better suggestions to make user roles much more flexible when they get added or deleted.
Also, what is the best way to display the page based on user roles, as I want some elements to be hidden according to the roles. Should I compare the role in each page and hide elements on every page? Is there a better solution?
Please shed some light on these.
Thanks
The sfDoctrineGuard plugin (http://www.symfony-project.org/plugins/sfDoctrineGuardPlugin) is a pretty comprehensive way of handling user authentication, groups and credentials. Users can be set permissions either individually or as a group, and access to specific page sections or entire actions can be restricted based on those permissions. You can set new user credentials in the controller code itself, e.g.
<?php
$this->getUser()->setCredential('editor');
?>
And verify that a user has particular permissions in views:
<?php
if ($sf_user->hasCredential('editor')) {
// stuff only for editors
}
?>
This page has lots of extra info on the plugin not covered by the readme file - http://trac.symfony-project.org/wiki/sfGuardPluginExtraDocumentation (although it refers to Propel rather than Doctrine). Also the following series of short tutorials is pretty useful:
http://www.finalconcept.com.au/article/view/symfony-user-management-sfdoctrineguard-installation
http://www.finalconcept.com.au/article/view/symfony-user-management-sfdoctrineguard-administration
http://www.finalconcept.com.au/article/view/symfony-user-management-sfdoctrineguard-securing-actions
And the Symfony tutorial page on users:
http://www.symfony-project.org/jobeet/1_4/Doctrine/en/13

What choices to make for an application backend

I am creating an web application and I at the point that i am starting to make backend choices. Now there are a lot of ways to go with this, so I am looking for some good points and back practices.
Some of the question i have involve:
Should i make a seperate table in the db for admin users
Should i extend make some classes to load the admin data and the normal data, or make seperate classes for the admin section
Where can i get some information on making different types of users
Just some best practices for a backend
My application is written in PHP with an MySQL database.
Keeping a separate table for admin users is nice, but only if those admin users aren't "regular" users as well - otherwise you'll step on your own toes trying to keep usernames/IDs unique but somewhat connected.
A couple things to consider:
Apache authentication (or Windows accounts on IIS) for admin users. Separate system entirely, but allows for overlap - a regular user can be a regular user, but they can't access any admin functionality until they authenticate through the browser. Works fine if you only have a couple specific kinds of user role (e.g. member & administrator only).
All users in one table, but with roles and permissions separate. This is the most flexible because you can get as granular as you need. For example, any user can "post comments," while an admin can "delete comments" and "ban users," but a moderator can only "suspend comments" and "mute users." As you add new features, it's simply a matter of implementing some new permissions & assigning them to the roles. Drupal's access control does this really well, worth a close look.
A good way to do it is to add a new field in the users table for 'rank' in order to differentiate between regular users and staff members, and possibly between the different staff member levels such as moderator, admin, etc. if you need it. Because an administrator should be able to perform all functions that a user can. Use
class Admin extends User { }
if you want to add additional functionality specific to staff members.
As for backend functions, that depends on how your site is set up. If you're using a framework, you can just add new functions to existing controllers and restrict access only to users with a certain rank.
For example, you might have a controller for ForumPost objects, but calling the ForumPost delete() function would require the user to be a forum moderator.
If you're not using a framework, you'll probably have to make your own pages for each backend function you need.

Zend Auth and ACL

I am hoping some can help me a little bit, I am currently developing my first site using a PHP framework, part of the site is spilt into a members area, this is where my confusion begins to surface, withing the members area I want normal members to be able to add new comments and edit there own comments, simple enough that I can just check the posters name against the username that is stored in the session, my confusion comes with differentiating between the 'normal' users and the higher level users who have the ability to delete and modify any ones comments etc, they should also be able to access the admin section of the site.
My question is should all user login through the same Zend_Auth controller, or should there be seperate controllers using Zend_Auth for each type of user or can all that be dealt with using Zend_Acl? Any help, advice, article, or tutorials would be greatfully appreciated. Personally I think the Zend documentation is a little raw on some classes.
Thanks in advance
sico87
I recommend the book "Zend Framework in Action" from Manning Publications as a great, up-to-date, introduction to this. It's available as PDF download, so you can have it now :)
But to answer this particular question:
Let's start by defining two key terms.
The "Auth" in Zend_Auth refers to Authentication, which proves someone is who they say they are (i.e. login).
The "A" in Zend_Acl refers to Authorization, which proves someone has the right to do what they're trying to do (i.e. access control).
Assuming the user has a single role...
Store the user's roles in the "identity" you get as part of Zend_Auth.
At login:
$auth = Zend_Auth::getInstance();
$identity = new stdClass();
$identity->user_pk = $user->getPrimaryKey();
$identity->user_name = $user->getName();
$identity->role = $user->getRole(); // select * from user_role where user_pk=xxx
$auth->getStorage()->write($identity);
In Controller:
$acl->add(new Zend_Acl_Resource('news'))
->allow('defaultRole', 'news');
Everything is denied by default, so you don't really need to specify:
->deny('defaultRole', 'news', 'add');
Further on in the Controller's code:
$identity = Zend_Auth::getInstance()->getIdentity();
if(!$acl->isAllowed($identity->role, 'news', 'add'))
{
header('Location: http://www.yoursite.com/error/unauthorized');
}
If the user's identity is not allowed to do "news->add", it will redirect them to the unauthorized page (assuming you've made such a page).
If the user had >1 role, you'd store an array of roles in their identity.
Then your check would go something like this:
$identity = Zend_Auth::getInstance()->getIdentity();
$isAllowed = false;
foreach($identity->role as $role)
{
if($acl->isAllowed($role, 'news', 'add'))
{
$isAllowed = true;
}
}
if(!$isAllowed)
{ // if NO ROLES have access, redirect to unauthorized page
header('Location: http://www.yoursite.com/error/unauthorized');
}
Hope that helps.
Yes, in most cases all of your authentication should go through the same controller. However, Zend Auth is not a controller type. Zend Auth is an API for utilizing common authentication methods like a database or http. Its job is really just to be a wrapper around the grunt work of writing authentication code.
Zend Acl is what you are looking for to distinguish between normal and privileged users. You only involve Zend Acl after the users have authenticated and logged in.
Most of what you need is in the ZF documentation. I read almost all of the documentation for Auth and Acl before it made great sense to me. Even though ZF's Auth, ACL, Storage_* and other classes are used very closely together, they all serve very distinct purposes. With a little time you will see that they build on each other nicely.
A couple of links to get you started:
Pádraic Brady's ZF Tutorial
Zend's DevZone article on ACL and MVC
I can understand why you are getting confused. I was/am still a bit confused. So, unfortunately I cannot answer your question directly. But, one thing i am doing in order to clarify all this stuff in my head is to think in terms of 'domain objects' as opposed to database records.
My tactic to deal with this issue is to create my own Auth Adaptor that is passed a 'User Base Object' along with the user credentials. My 'User Base' is kind of like a repository of users.
So the Zend Auth is left being 'an interface' to other Zend Components whilst i still have a bit more control over my system for storing and accessing 'Users'.
My User_Base class could be a wrapper around a Zend Db tbl or even just have some hard code in it that i can use for testing.
So in general-
design your own model of a 'user'
design your own Auth Adaptor - starting with the minimum interface required as outlined here: http://framework.zend.com/manual/en/zend.auth.html
and just keep it all simple and go slowly as you learn more about it.
well that's what i am gonna do anyway.
I aint even gonna bother with Zend ACL just yet til i have Auth clear in my head.
I'm revamping a legacy site and converting it to Zend MVC
These are some things (perhaps unconventional) that I have had to get to grips with for my 'model' to work. :
an app may be used by users from multiple 'user bases' - openID, legacy users table, new users table, fleeting guests, etc
a guest's identity might just be a hash created when they first arrive
whereas, a legacy user's identity might be represented by an id in the legacy users table
users and user_accounts are separate things. don't try to mix them into one concept cos it could get complicated.
there may be many different types of accounts in the system. I.e. Buyers Accounts versus Sellers accounts. Readers_Account versus Writers_Account
accounts 'have' users - 'primary account holder', 'admin super user', etc
the relationship between the users and an account are represented by, say, 'account_users' (a local subset of all users in all user bases)
roles arew attached to account_users (the users of that particular account).(As opposed to roles floating around )
don't be afraid to have more than one Zend application on a server to represent a website - e.g admin app, members app, front end app.
don't be afraid to let these apps use model objects stored in say 'shared models' folder, with the only model code that directly relates to the individual app sitting in the /application/models/foomodel folders.
each app might have its own custom Auth adaptor
an admin auth adaptor may only allow users from the 'admin users table' whereas a front end app's Auth adaptor might be able to authenticate users from the guest userbase, staff, or members user base.
might be a speical case where front-end apps session is cleared and replced by member session upon elevation when member logs in.
one user object per app per webclient at anyone time (as opposed to trying to reference a person with a guest user AND a member user - that's too complicated)
one session per user per app (namespaced to avoid conflicts with other apps that they may be logged into on that domain) - (as opposed to trying to simultaneously refer to 'the person using it' with a guest session AND a member session. again, that's too complicated)
ok i am starting to ramble....but you get the idea. Don't let the Zend_Auth+Zend Db tutorials that you see sway your own model. they are just simplified examples.
nuff said
I have a few questions about this piece of code
$auth = Zend_Auth::getInstance();
$identity = new stdClass();
$identity->user_pk = $user->getPrimaryKey();
$identity->user_name = $user->getName();
$identity->role = $user->getRole(); // select * from user_role where user_pk=xxx
$auth->getStorage()->write($identity);
$identity = Zend_Auth::getInstance()->getIdentity();
Are user_pk, user_name and role stored as cookies? Will someone that makes a cookie with the role-name able to access the secured parts of the websites? Shouldn't a password (with md5-encryption) be part of the identy as well so when can verify username and password with each request?

Categories