0

I'm trying to create a fosuserbundle for a quite strange use case, which is mandatory requirement, so no space to diplomacy. Use case is as follow:

  • users in a mongo db table populated by jms messages -no registration form
  • users log in by ldap
  • user record not created by ldap, after a successful login username is checked against mongodb document

Considering that ldap could successfully log in people that exhist in ldap but cannot access site (but login is still successful), what could be the best way to perform such authentication chain?

I was thinking about some possible options:

  • listen on interactive login event, but imho there's no way to modify an onSuccess event
  • create a custom AuthenticationListener to do another check inside onSuccess method
  • chain authentication using scheb two-factor bundle

any hint?

Matteo Rossi
  • 303
  • 3
  • 10

1 Answers1

1

I've used Fr3DLdapBundle which can be incorporate with FOSUserBundle quite easily (I'm using the 2.0.x version, I have no idea if the previous ones will do the same or be as easy to set up).

In the LdapManager (by default) it creates a new user if one is not already on the database which is not what I wanted (and doesn't seem to be what you want) so I have added my own manager that checks for the presence of the user in the database and then deals with the accordingly.

use FR3D\LdapBundle\Ldap\LdapManager as BaseLdapManager;
.. Other use stuff ..

class LdapManager extends BaseLdapManager
{
    protected $userRepository;
    protected $usernameCanonicalizer;

    public function __construct(
        LdapDriverInterface $driver,
        $userManager,
        array $params,
        ObjectRepository $userRepository,
        CanonicalizerInterface $usernameCanonicalizer
    ) {
        parent::__construct($driver, $userManager, $params);

        $this->userRepository = $userRepository;
        $this->usernameCanonicalizer = $usernameCanonicalizer;
    }

    /**
     * {@inheritDoc}
     */
    public function findUserBy(array $criteria)
    {
        $filter  = $this->buildFilter($criteria);
        $entries = $this->driver->search(
            $this->params['baseDn'], $filter, $this->ldapAttributes
        );

        if ($entries['count'] > 1) {
            throw new \Exception('This search can only return a single user');
        }

        if ($entries['count'] == 0) {
            return false;
        }

        $uid = $entries[0]['uid'][0];
        $usernameCanonical = $this->usernameCanonicalizer->canonicalize($uid);

        $user = $this->userRepository->findOneBy(
            array('usernameCanonical' => $usernameCanonical)
        );

        if (null === $user) {
            throw new \Exception('Your account has yet to be set up. See Admin.');
        }

        return $user;
    }
qooplmao
  • 16,754
  • 2
  • 38
  • 63
  • indeed I ended up providing my own user provider, but I think your solution si more correct and adherent to symfony and bundle standards. – Matteo Rossi Nov 10 '14 at 09:56