I'm using fr3d/ldap-bundle. It logs me in and imports users from AD if they're not in db. That's fine. 
Despite AD users I also have local users, which are in my db. There is special column authType which says how user should be authenticated - via LDAP or natively ( FOS ). I've created my own user provider:
public function chooseProviderForUsername($username)
{
    if($user->getAuthType() == User::LOGIN_LDAP) {
         $this->properProvider = $this->ldapUserProvider;
     } elseif($user->getAuthType() == User::LOGIN_NATIVE) {
         $this->properProvider = $this->fosUserProvider;
     } else {
         throw new InvalidArgumentException('Error');
     }
}
public function loadUserByUsername($username)
{
    return $this->chooseProviderForUsername($username)->loadUserByUsername($username);
}
PROBLEM: Chain provider isn't an option - it allows user to login with his LDAP password AND with his local password! That's a big security issue.
Is there a way to login user via different authentication providers, depending on the db field?
EDIT:
My security.yml:
 providers:
        fos_userbundle:
            id: fos_user.user_provider.username
        appbundle_user_provider:
            id: appbundle.user_provider
        fr3d_ldapbundle:
            id: fr3d_ldap.security.user.provider
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        admin:
            pattern: ^/admin.*
            context: user
            fr3d_ldap:  ~
            form_login:
                provider: appbundle_user_provider
                csrf_provider: security.csrf.token_manager
                always_use_default_target_path: true
                default_target_path: admin_main
                login_path: /admin/login
                check_path: /admin/login_check
            logout:
                path:   /admin/logout
                target: /admin/login
            anonymous:    true
Here is security.yml. This line fr3d_ldap:  ~ enables the ldap bundle, which authorize ldap users and saves them into my db. Without it I cannot authorize them,  probably I would have to write custom AuthenticationProvider. 
I am not very familiar with ldap but I would suggest try doing a completely manual login
  $token = new UsernamePasswordToken($user, null, "firewallname", $user->getRoles());
  $securityContext = $this->container->get('security.context');
  $securityContext->setToken($token);
Then you can manually do the checks yourself, and depending on the result of the check decide how you want to verify the user before authenticating. For example, run a query by username and password before executing this login code or whatever, depending on the db field you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With