Thanks to visit codestin.com
Credit goes to github.com

Skip to content

symfony/security - tagging UserCheckerInterface #11090

Closed
@linaori

Description

@linaori

Security - tagging UserCheckerInterface

When working with custom authentications, you most likely want to implement a custom UserChecker. The standard "form" supports this but doesn't really allow customization. "simple_form" does not have a standard implementation for this, sadly.

Proposal

I came to the conclusion that it might be a lot easier to add some custom account/user validation. I was creating my own Authentication and user provider and stumbled against the choice to implement the Simple variant or the normal (older) variant.

One of the main reasons I couldn't implement the existing variant, was due to the lack of customization of the UserChecker. Before loading the user, I had to know if the user was supposed to see a captcha or if the IP of the user was blocked. Before the authentication, I wanted to know if the account had any blocks. After the authentication, I wanted to load a secondary Entity that I would check some additional account statuses. I could not work around this with existing code so had to write a custom provider for this.

A simple solution would be to allow the firewall options for a certain authentication method to allow passing the ID of a custom service. This would mean you'd get the following option:

security:
    firewall:
        secured_area:
            (simple_)form:
                user_checker_service: my.user_checker

As long as your service would implement the UserChecker Interface, this would all be possible. However, this isn't really flexible... You could do the following:

security:
    firewall:
        secured_area:
            (simple_)form:
                user_checkers: 
                    - my.user_checker.ip_block
                    - my.user_checker.captcha_block
                    - my.user_checker.banned_account
                    - my.user_checker.accepts_latest_eula
                    - vendor.bundle.extra_user_check

With this solution, you would be able to add extra checks on demand. It would be a really nice addition to work with the Simple provider as well, but that would introduce BC breaks, but solve a lot of nasty code.

class MyBannedAccountUserChecker implements
    PreUserLoadCheckerInterface,
    PreAuthUserCheckerInterface, 
    PostAuthUserCheckerInterface
{
    public function checkPreUserLoad()
    {
        // additional checks BEFORE the user is being load...
        // good example is to check IP block, captcha's, other requirements
    }

    public function checkPreAuth(UserInterface $user)
    {
        if (!$user instanceof MyUser) {
            return;
        }

        // .. get the entity where ever you store if the user is banned

        if ($banned) {
            throw new AccountBannedException($user); // extends AuthenticationException
        }
    }

    public function checkPostAuth(UserInterface $user) { ... }
}

I think this example should demonstrate exactly what I mean. This will give you flexibility while it will also make it easier to configure the security component user checks. I have noticed examples of people who are totally lost in this component and have no clue where to add the custom checks for this. As far as I know it's only possible to modify the current existing UserChecker by a CompilerPass. It's tightly coupled with the "form" login method and the only available implementation works only with the AdvancedUserInterface (which imo should be rm -rf'd).

To prevent backwards incompatibility issues, the current UserCheckerInterface should not be removed, although the splitting of pre and post auth checks can cause a minor inconvenience.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions