Force reauthentication after user permissions have been changed - symfony

In my application I can change user permissions and roles in backend.
When a user is logged in and I remove a role of the user, the user can still access content which he actually is not permitted to access anymore, because he is missing the role. The changes take effect only when the user reauthenticates himself with logout/login.
So my question is, can I access the session of a logged in user (not me)? I know I can access my own session and destroy it which forces me to login again. But I want to get the session of any user who is logged in. Is this possible? I could not find any resources about that.
I use PdoSessionStorage with symfony2.1 and fosuserbundle.

Make your user class implement Symfony\Component\Security\Core\User\EquatableInterface.
If you return false from the isEqualTo() method, the user will be reauthenticated. Use that method to compare only those properties that when changed should force reauthentication — roles in your case.

You can get around this issue by following an approach similar to what I did:
When user logs in, store all permissions in session along with a checksum of those permissions.
Store the same checksum in a database, or on disk, against that user ID
Whenever the user makes a request, verify that the checksum on disk matches the one in session for that user. If it is different, reload the permissions into the user's session
When you change the permissions, update the checksum in the database (or on disk) that is stored against that user. This will trigger a resync on their next request.

Related

asp.net identity 2 require particular claim to log in

In MVC5 asp.net - Is there a way to allow user login only if the user has a particular claim in the user database? I'd like to assign a "CanLogin" claim to users in my user database that are allowed to log in at any given time. By removing the "CanLogin" claim, I could effectively lock the users out of the system until further notice.
This would have to work for a first time login as well as cookie login at a later stage if the user has checked "remember my login".
Using authentication filter, you can check the identity.claims property to validate whatever claims are present in the context.
The claims must be added during the login process
Then you can check whether a particular user is enabled or not.
However, if the user database is self maintained, you can just set a disabled flag and then reject the login request, instead of returning such a claim.
The claims are used for Authorization to a particular functionality rather than Authentication to an app. A valid user will have certain claims which can tell what all the user is permitted to do.

Symfony 2 track anonymous user actions in database

I would like to track anonymous user actions as if the user would be authenticated. The goal is to let users perform actions(normally reserved to authenticated users), save it in Database with a special status (not visible until user will log into the application).
For example,
an anonymous user reply to a comment.
The system detect that the user is not logged in, save the comment with special status 'waiting for authentication'.
The system ask user to log in, in order to complete the registration of the comment.
User log into the application.
The system check for 'waiting for authentication' status and update/associate entries to the user authenticated.
Have you any suggestions / experiences to implement this type of functionality? Maybe Symfony has already in feature/bundle for that?
What you are trying to do is simillar to Lazy Registration, which is a proven concept. It is well implemented here at stackoverflow. It allows you to post messages after providing an email address. It works similar to this one:
http://www.90percentofeverything.com/2009/03/16/signup-forms-must-die-heres-how-we-killed-ours/
However, if you really want to go your way, without asking user for an email address, I would recommend storing data at browser local storage. It would save you a lot of work on backend side. Data would be transferred to the backend only when user registers. This way you will also prevent database pollution with users who never registered. http://blog.teamtreehouse.com/storing-data-on-the-client-with-localstorage
You could use ip address but it won't be very effective because one user can access your website from many ip addresses (wifi, 3g/4g connection ...).
You can rely on cookies but once he logs in from another device you can't do anything about it.
IMO, you should save actions and link them to a uniq token that you send to the anonymous user, once he's authenticated he can provide the generated token and then you save actions for that user. Becareful to not forget removing saved anonymous-actions once they are "identified".

Avoid two or more login with the same user at a time using FOSUserBundle

I'm trying to avoid two or more login with the same user at a time using FOSUserBundle in Symfony 2.4, I don't know how to access to info related to authenticated users and how to logout if the user who recently logged in are previously authenticated.
What am I missing?
[edit]
Reading your question again i am not sure what you want. The answer i wrote below keeps the latest login alive and logs the older logins off
[/edit]
a user that is logged in has
a) started a session on the web server
b) identified his self by entering a correct username and password combination.
That knowing we know also that a user that is logged-in has a variable in stored in the session (probably user_id).
Now if you want to logout other sessions (with same user_id) if a users logs-in in another session, you do have a problem since sessions are not made to share information with other sessions.
The solution could be to add a column in your database 'users' table that can hold a random hash. Then if a user logs-in you need to save a new hash in the database and also you need to save the hash into the session.
Then secondary you have to compare the session hash with the database hash for every new request. If the two are different and the user is still logged-in than you have to log the user out.
I think you can let this work with following event-listeners (but i never tried to accomplish this):
security.interactive_login
kernel.request

ASP.NET MVC authenticates and authorizes non-existent users

I'm using the DropCreateDatabaseAlways Initializer so my database gets destroyed every time I start the application (at least I hope so). The funny thing is I still see myself as logged in. I get pass the Authorize attribute and can do dangerous stuff. This is probably because of leftover cookies from previous testing.
Registration/login part of my app is the MVC 4 Internet Application template untouched. Shouldn't ASP.NET check the cookie values against users saved in the DB? WebSecurity.IsAuthenticated returns true and WebSecurity.CurrentUserName returns the name.
The only thing working as expected is WebSecurity.CurrentUserId which returns -1. I'm a newbie so I can only guess this is because UserId isn't stored in the cookie and must be retrieved from the database.
Am I right? If so, does it mean I should always use WebSecurity.CurrentUserId to determine whether a user is logged in? WebSecurity.IsAuthenticated and User.Identity.IsAuthenticated seem pretty useless in that case. I can delete a user's account and he or she remains unaffected. What should be done differently if I am wrong?
If you want to realiably check whether a user has not been deleted, you just have to consult the database.
Note that users and administrators work concurrently. This means that a user can be deleted just a second after he has been authenticated. A cookie can be then even one or two seconds old (!) and the user could probably have been just deleted.
In a most pessimistic scenario, a user types a valid username and password and is succesfully logged in and get the "sorry, your account has been deleted" just one request later (because the account has really just been deleted).
There will be a small window where if a user is deleted and they are still logged in that they can still access the site. Since most actions require a validate user id, you can simply throw an excpetion and log the user out.
Normally the database does not get blown away on each build, so I'm guessing this is not a use case SimpleMembership was coded for. You can of course check for this. I'll make another assumption that you are not closing your browser when you rebuild the site and deploy the new database. In a real world scenario these things just don't happen. The database is never blown away and the user id is never lost.
Generally once you've logged in the user, the user is not authenticated anytime after that (unless they have logged out, or the session has expired). That's the point of login. The authentication cookie is an indication that the authentication happened and was successful. The assumption going forward is the user has access to your site and is not reauthenticated.
As long as the authentication session remains open (i.e. browser now closed), the session cookie remains active and MVC assumes that the user is still valid.
Remove the cookie by using FormsAuthentication.LogOff() if the user is authenticated (User.Identity.IsAuthenticated == true) and there's no valid user in UserTable (WebSecurity.CurrentUserId == -1).
I had the same issue, but solved it by specifying the required role(s) in the Authorize attribute. As soon as you do this, it start getting to the database and fails with the "user does not exist" error, which is what you want.
[Authorize(Roles = "Customer")]
public class DashboardController : Controller
In normal case adding Session.Abandon(); to to your LogOff action in AccountController would do the job of clearing session:
public ActionResult LogOff()
{
FormsAuthentication.SignOut();
Session.Abandon();
return RedirectToAction("Index", "Home");
}
So I think you can try adding Session.Abandon(); in init code, where you use DropCreateDatabaseAlways to clear session each time.
The ticket issuing time is usually encrypted within the authentication cookie then you can use it to require re-authentication to sensitive areas (inbox/billing etc.) if more than X time passed since login.
If you insist on invalidating all current auth tickets upon application changes (i.e database/configuration) you can change this settings in your web.config:
<machineKey validationKey="..." decryptionKey="" />

Invalidate another users session variables

I'm thinking of a situation where an administrator makes some changes to another user in the system that happens to be logged in. Is there any programatic way to invalidate that specific users session variables and force them to be repopulated?
Use Case
Admin Edits Bobs preferences
Business Logic clears bobs preferences stored in session
Preferences saved to database
Thanks
One way is to clear the other user's session cookie.
The other way is to create your own SessionIDManager (derive from the built-in one). Then when the Validate method is called with the other user's session ID, you can return false.

Resources