I have written a system in which a background PHP process (written using the RabbitMQBundle) processes messages from a message queue. The worker process updates user accounts. This may include a change in the user roles.
The problem is that a user won't notice any changes in his roles while being logged in. The new roles only get applied after logging out and in again. From a security perspective this is not desirable. A user should loose any role as soon as an administrator takes away privileges from that user in the backend system.
The question is: How can a session for a specific user be updated with the new roles? Or when that is not possible, how can the session be invalidated?
Note that in the background process we don't have an active security.context or request that we can use. Code like this therefore doesn't work:
$this->get('security.context')->setToken(null);
$this->get('request')->getSession()->invalidate();
You can solve this in several ways:
1) via security.always_authenticate_before_granting
You can force Symfony to refresh user on each request, effectively reloading all roles with it.
See this SO question/answer:
Change the role of a distant user without having to relog
2) Via EquatableInterface:
You need to implement isEqualsTo(User) which in turn should compare everything with User class, including roles.
See this link: Create a User Class
3) Finally, you can use DBMS to store sessions. Then, it's just matter of find the record and delete it.
Related
Current app:
The app I'm working on has a single User entity.
Users can be "member" or "manager" using a boolean attribute stored in database (is_manager).
All the users connect trough the same routes (/login) and are redirected depending on the attribute is_manager.
Here is my problem:
The client want to be logged as a "member" in one tab and an other user "manager" in an other tab of the same browser.
Not several "members"/"managers" at the same time in the same browser.
How can I acheive it with Symfony 3.3 ?
Based on my idea the session ID should depend on the attribute is_manager but I'm not really sure of it and don't know how to do it with Symfony.
Any help will be really appreciated!
You could use User switching to almost solve this problem. Instead of logging in as member or manager, they login as a user with the role ROLE_ALLOWED_TO_SWITCH. You can then provide links to the page they want to see with an added attribute ?_switch_user=member_user or ?_switch_user=manager_user. Both those users have to exist and need the correct permissions.
This may not be perfect, for example you have to maintain 3 different users for 1 account and you have to make sure they don't accidentally perform actions after switching the role, but that is the best way I can think of, to support this kind of switching.
You need to tune up your user management system. You can put some vars in your session saying to your system to behave un some way (manger or user) but if it must depend on the open tab, then the best approach that I can think of, is using the url. Put some kind of token (secured one, of course) on the url that tells your system how to deal with that user.
On this approach, if the user closes the tab, it becomes automatically logged out, at least in one of it's roles.
So you can do a standard login process, set the session for the manager role (the more privileged one) and the build and present a link to the user to he non manager versión. That url contains the mentioned token, and if he closes the tab and wants to recover the tab, it should go to the manager versión and follow the link again.
zend framework how to reload session while submit the action.
user may have more than one user level permission,
i have form which contain user rights in check box,
i want to reload session values who are all currently logged in the web.
Example:am admin, currently x and y users are logged in in to the web and doing some activities, their rights are admin, super admin user rights,
i am admin i want to remove their super admin rights, if the made change than these rights changes should change immediately who currently access the web site users also.
How to achieve this in zend.
If I understand correctly, it sounds like you want to update privileges/permissions associated to a role (admin, super-admin, etc) and then have those updated permissions apply to all users with that role, even the ones who are already logged-in.
This is actually not a ZF-specific problem. It relates more to how you structure your session handling, in particular, whether you store the user's roles/permissions in the session, whether you query the db/datastore for those, etc.
If you store only the core user info in the session and you query for roles and permissions on each request (probably the least performant of the options), then your problem is solved. The roles and permissions have been updated in the datastore and will be reflected when you query for them.
Alternatively, if you also store the roles and permissions in the session, then you need to iterate over all active sessions, updating privileges in sessions affected by the new role. While this is technically do-able with file-based sessions, it is usually done using db-based storage for your session.
As noted elsewhere, Zend_Session and Zend_Acl are the components providing all this functionality. But the decision on core architecture has to precede implementation with these components.
I am a novice php programmer building a multiuser application in codeigniter.
Now, my boss has told me to look into the ability to log out people based on their changed user access privileges.
Fx. A guy is logged in as a semi admin, but has just been demoted by a real admin to regular user status. Now the semi admin should supposivly be logged out when that happens but this is where my problem occurs.
I can think of a few ways to do this but they all revolve around doing checks that will be redundant in most cases (this is a rare situation but it has occured, i have been told)
My best bet at the moment is to log all the active users in a session db and force them to relog in if their user role changes.
This however is going to generate a lot of trafic on the server for a rare "problem" as the user session data is more fittingly put into a regular session.
So my question in short is, how can i log out a user when his user privileges are changed, without working my server too hard.
Thanks in advance!
You can check if privileges have changed periodically, like once every 10 minutes, this should reduce the amount of "useless" queries and still ensure that there is an acceptable response time to a logged in user privileges being changed.
Add a javascript listener on the page then, when the super admin changes the semi-admin privileges to a normal user, trigger the logout event. Make sure that the app has javascript enabled, otherwise it won't work. This solution is used by many ACL-based apps.
I`am using symfony2. When I change some user role I would like that the roles would be change immediately even when that user is currently logged.
I have found something like this:
$this->get('security.context')->getToken();
$token->setAuthenticated(false);
But this is done within the current user. I would like to do this for another user.
I am not changing the roles for user which I am logged in. I am changing it for another user, who is possibly logged in.
Any help would be appreciated.
P.S. Storing session in database is not acceptable for my problem.
You could create a table with a commands for example to log out a specific user, and then create a listener so when the user is refreshed from database (eg. when he creates another request) then this commands are taken into place and the code logs out the user.
You cannot really control somebody else session.
About specific roles, it should be fine to just update the user roles in DB because the user is refreshed with every request.
I've seen a few instances now where web applications are letting try them out without you having to sign-up (though to save you need to of course).
example: try at http://minutedock.com/
I'm wondering about doing this for my own web app and the fundamental question is whether to store their info into sessions or into a temp user table?
The temp user table would allow logging and potentially be less of a hit on the server, correct?
Is there a best practice here?
It should work exactly the same way the application usually works, with the only difference being that a flag like thisIsATrialUser is set. You shouldn't create two different ways to do things internally.
Create a class of user, lets call it your Anonymous User Type. Give all unauthenticated users anonymous accounts (you have to clean up old accounts at some point). Use a persistent cookie to associate old users with their anonymous account. Make them authenticate themselves whenever they need to perform something that requires payment or full registration. Change their user type to something like Regular User Type once they are authenticated so you can keep all the information that was already attached to them when they where anonymous.
This allows tracking and storing of potential information like shopping carts without requiring registration upfront. Your code shouldn't have to change much if you treat anonymous user similarly to regular users. Otherwise you have to create an entirely new set of code to manage special users that are not stored in your master user table.
To clean up the data added by trial users, you can create a script to delete all the data that was created lifetime of cookie + 1 day and owned by any trial user. You can auto-pilot the script with nightly cron.