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.
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.
I have a problem in my project. When admin is logged in, no front end user can login in the same browser, why this happens? But when I destroy the cookies and then tries to login as user it correctly logs in.
How can I solve this?
Any major browser will only store one session cookie for a site, but the site developer gets to choose what's in that cookie. It seems like your site is storing user information in the session cookie, which is then getting overwritten when the other tab stores different information in the same cookie.
You don't provide much detail about how your specific site operates, but here are a few general ways of approaching this problem.
1) Use different browsers for different users. Different browsers don't share cookies between them. If your goal is simply to test your site with multiple users, this is the way. You can also use Incognito/Private mode to log in a separate user, as this mode doesn't share cookies either.
2) Don't use session cookies to store user information. This is a non-starter on most websites, but if this is an internal site or strictly controlled environment, you may be able to pass user identification via the URL, POST data, or some other hidden identifier in the request.
3) Store data in the session cookie for all currently logged in users. Depending on the web framework, it may be possible to create a map of user -> cookieData and look up the correct one based on which user is making the request. This is an advanced technique, and I don't actually know if Laravel exposes this level of control.
Harshad is covering all the aspects very well, but I can tell about a little trick a I have used when I wanted to test using different user rights (same browser). In my case, it was Windows Authentication, but it does not matter:
1) define a flag at user level (e.g. SuperUser). It can be 0 (false) or 1 (true).
2) allow "impersonation" - if an administrator has SuperUser flag set, he/she can change its roles/rights and see the site as if he/she is a normal user with that particular rights, but user management section is still accessible, to allow changing rights back.
3) Little changes are required in the user management section to allow SuperUser security implementation (i.e. section is showing if user does not have admin role, but it is marked as SuperUser)
So, you are testing as a single user, no multiple session cookies or other tricks are required. You can have one tab opened with your user profile and other(s) to do the actual testing.
Note: regarding the multiple browser suggestion, it is a quick solution for developers, but in corporate environment, this can be a real problem, as users (e.g. key users that have to test security) do not have access to more than one browser.
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.
I am fairly new to PHP programming and I think I might have some security issues with session variables.
I am currently working on a project which has 3 modules which require separate login credentials.
The 3 modules are for students, teachers and administration.
After the user logs in the respective portals, these credentials are stored as session variables. Let's say we have 2 tabs open in the browser, 1 has the student portal open and the other has the admin portal open. If the student logs in the first portal with user id 1 shortly after the admin has loged in with user id 2, then the userid for both the portal appears to be the same(userid 1). The problem is the session variables for both the portals are getting shared in the browser.
Sometimes session variables are also pulled from previous session in a new tab even after closing it.(*tested it using var_dump[$_SESSION]*)
Can somebody please explain to me how to limit the session variables to each portals or provide me with some hints about other ways of security handling in php?
PS: I have logout buttons which clears up the session variables. The problem seems to persist if the tab is closed or a new portal is opened in the new tab.
thanks in advance.
From a browser to a server only one PHP session will be started (apart from private browsing options, but that's off topic) and that is "shared" among all tabs. In contrast to what #fejese's answer suggests, you can solve your situation with using only one PHP session. Your problem probably is that you use the same session variable to indicate that someone is logged in regardless of the access level of that logged in user.
As your 3 separate modules handle authentication, create 3 different session variables that indicate which user is logged in. For e.g. when a student logs in, craete $_SESSION['auth_student_id'] and assign the logged user (student) ID to it. When a teacher logs in, create $_SESSION['auth_teacher_id'], and so forth.
Then, depending on which portal is loaded, ignore the other session variables. So if in tab 1 the student portal is loaded, check for $_SESSION['auth_student_id'] and ignore the others. If that is set, you know the portal should show protected content because the user (student) has authenticated themselves. If in tab 2 the teacher portal loaded do the same with $_SESSION['auth_teacher_id'] and ignore the other 2.
You have some options:
Change "session_name" on a portal basis
If you change the session name, the cookies that identify the session will be different from portal to portal. Note that no session will be shared this way. If the user logged to a portal, he'll need to log again to the others.
Implement session namespaces
You could set an array in the main $_SESSION object, one for each submodule, and use each array as if you are using the session directly. With this approach you can share the sessions (easily implementing SSO between the portals), but raises some security concerns. It's valuable to implement an API to access the session if you go this way.
I'm using php sesions with mongodb by defining the
session_set_save_handler()
if every user has a role (client, admin, employee) ,
with every page I load after getting the session id i'm checking the value of the role
is this a secure approach ? or they can by pass that ?
The session data should contain the "state" (i.e. logged in or not logged in) of a user, but not specific details like a user's role.
So once a user is authenticated, you can then lookup information on the user in the database. If that user has the required role, then load the page; if not, then don't.
What you shouldn't be doing is logging the user in, creating a session for that user and also storing in that session the role. If you do it this way, you're potentially leaving your website vulnerable to loop-holes (especially on shared hosting). Also, what if a user's role changes during the lifetime of the session? Either you ask the user to login again, or the change in role isn't actually "registered" until the session is destroyed (which could be long time, depending on configuration).