Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony authentication providers

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.

like image 516
mmmm Avatar asked Jun 09 '15 13:06

mmmm


1 Answers

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.

like image 89
Joe Yahchouchi Avatar answered Oct 27 '22 19:10

Joe Yahchouchi