Search code examples
phpsymfonysymfony-securitysymfony5

How to immediately disable access to a user that is soft-deleted or no longer enabled?


In my application, users with the role ROLE_ADMIN are able to manually disable other user accounts, by setting enabled on the user account to false.

Using a user checker, the user will not be able to log in the next time they try:

public function checkPostAuth(UserInterface $user)
{
    if (!$user->isEnabled()) {
        throw new CustomUserMessageAuthenticationException(
            'Account is not enabled.'
        );
    }
}

My issue with this, it only works when a user tries to log in. If a user is currently logged in (could also be using the remember-me-functionality), nothing happens until they logout.

Is there any way to immediately disable the user from making requests to routes it no longer should have access to, even when this user is currently logged in?

What I could do is check if the account is enabled for every route that requires this user access, like so:

if ($this->getUser()->isEnabled() === false) {
    throw new \Exception("Account disabled");
}

But this seems like a terrible solution because I would need this in many places.


Solution

  • If you implement the Symfony\Component\Security\Core\User\EquatableInterface in your User class, the User will be logged out when isEqualTo() returns false.

    class User implements Symfony\Component\Security\Core\User\EquatableInterface
    {
        /* ... */
    
        public function isEqualTo(UserInterface $user)
        {
            if (!$user instanceof User) {
                return false;
            }
    
            if ($this->enabled !== $user->enabled) {
                // Forces the user to log in again if enabled 
                // changes from true to false or vice-versa.
                // This could be replaced by a more sophisticated comparison.
                return false;
            }
    
            // do a bunch of other checks, such as comparing the 
            // password hash: this will cause the user to be logged 
            // out when their password is changed.
    
            return true;
        }
    
        /* ... */
    }
    

    Relevant documentation