skip to Main Content

Im using symfony 6 and easyadmin 4.
Im trying to figure out how to block a user account on my website but
i can’t find a solution.

I tried to create a role named: ROLE_BLOCKED and then use a function like IsDenied in the controllers to block the access but it seems like they are no such function in symfony 6.

update:
here is my LoginAuthenticator


class LoginAuthenticator extends AbstractLoginFormAuthenticator
{
    use TargetPathTrait;

    public const LOGIN_ROUTE = 'app_login';

    public function __construct(private UrlGeneratorInterface $urlGenerator)
    {
    }

    public function authenticate(Request $request): Passport
    {
        $email = $request->request->get('email', '');

        $request->getSession()->set(Security::LAST_USERNAME, $email);

        return new Passport(
            new UserBadge($email),
            new PasswordCredentials($request->request->get('password', '')),
            [
                new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
            ]
        );
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
            return new RedirectResponse($targetPath);
        }

        // For example:
        // return new RedirectResponse($this->urlGenerator->generate('some_route'));
        throw new Exception('TODO: provide a valid redirect inside '.__FILE__);
    }

    protected function getLoginUrl(Request $request): string
    {
        return $this->urlGenerator->generate(self::LOGIN_ROUTE);
    }
}

and my security.yaml:

    # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
    password_hashers:
        SymfonyComponentSecurityCoreUserPasswordAuthenticatedUserInterface: 'auto'
    # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: AppEntityUser
                property: email
        # used to reload user from session & other features (e.g. switch_user)
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            provider: app_user_provider
            custom_authenticator: AppSecurityRegisterAuthenticator
            logout:
                path: app_logout
                # where to redirect after logout
                # target: app_any_route

            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#the-firewall

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

    role_hierarchy:
            ROLE_ADMIN:   ROLE_USER
            ROLE_ARTIST:  ROLE_USER

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
         - { path: ^/admin, roles: ROLE_ADMIN }
         - { path: ^/profile, roles: ROLE_USER }

when@test:
    security:
        password_hashers:
            # By default, password hashers are resource intensive and take time. This is
            # important to generate secure password hashes. In tests however, secure hashes
            # are not important, waste resources and increase test times. The following
            # reduces the work factor to the lowest possible values.
            SymfonyComponentSecurityCoreUserPasswordAuthenticatedUserInterface:
                algorithm: auto
                cost: 4 # Lowest possible value for bcrypt
                time_cost: 3 # Lowest possible value for argon
                memory_cost: 10 # Lowest possible value for argon

FINAL UPDATE: I solved the problem by using a userChecker CLass

2

Answers


  1. use SymfonyComponentSecurityCoreSecurity to get user details and add condition based on the status. or you can directly use isEnabled method

    public function isEnabled() {
        return $this->getIsActive();
    }
    
    Login or Signup to reply.
  2. To achieve what you want, you need to:

    1. Store users status (able to connect or not)
    2. Prevent user from logging in
    3. Be able to disable an user with EasyAdmin

    To enable/disable users, you could just add a new $isEnabled property:

    /**
     * @ORMColumn(type="boolean", options={"default":true})
     */
    private bool $isEnabled = true;
    
    public function isEnabled(): ?bool
    {
        return $this->isEnabled;
    }
    
    public function setIsEnabled(bool $isEnabled): self
    {
        $this->isEnabled = $isEnabled;
    
        return $this;
    }
    

    Don’t forget to update your schema (with a new migration)


    To prevent your user from logging in, if you are using the new authenticator system (5.3+) you could just update your getUser method and add something like:

    if (!$user->isEnabled()) {
        // fail authentication with a custom error
        throw new CustomUserMessageAuthenticationException('Account is disabled.');
    }
    

    And finally just add your new isEnabled boolean to your crud controller:

    public function configureFields(string $pageName): iterable
    {
       //...
       yield BooleanField::new('isEnabled');
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search