Modifier

Le but est d'avoir une autentification via lemonLDAP (utiliser comme firewall de plusieurs applis) et que Symfony récupère l'utilisateur du LDAP pour faire la corespondence avec un utilisateur dans sa db.

le dépot framagit

dans notre exemple l'entité utilsiée est Indidivdu et va implémenter UserInterface

On créer un IndidivduRepository pour associer la donné Auth-User du header et le champs corespondant de l'entité Indidivdu (ici matricule).

namespace AppBundle\Entity;

use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;

class IndividuRepository extends EntityRepository implements UserLoaderInterface
{
    public function loadUserByUsername($matricule){
        return $this->createQueryBuilder('i')
            ->where('i.matricule = :matricule')
            ->setParameter('matricule', $matricule)
            ->getQuery()
            ->getOneOrNullResult();
    }
}

ensuite on configure le fichier app/security.yml

security:

    providers:
        header:
            entity:
                class:  AppBundle:Individu

    firewalls:

...

        backoffice:
            pattern: ^/admin
            remote_user:
                provider: header
            stateless: true
            simple_preauth:
                authenticator: app.security.headerIndividuProvider

...

    access_control:
        - { path: ^/admin, roles: ROLE_USER }

on créer le service de préauthentification pour charger systématiquement l'utilisateru à partir du Auth-User du header, dans le fichier AppBundle/Security/SsoAuthenticator.php

namespace AppBundle\Security;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface;

class SsoAuthenticator implements SimplePreAuthenticatorInterface
{
    public function createToken(Request $request, $providerKey)
    {
        $headers = apache_request_headers();
        $authSso = $headers['Auth-User'];

        if (!$authSso) {
            throw new BadCredentialsException();
        }

        return new PreAuthenticatedToken(
            'anon.',
            $authSso,
            $providerKey
        );
    }

    public function supportsToken(TokenInterface $token, $providerKey)
    {
        return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
    }

    public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
    {

        $authSso = $token->getCredentials();
        $matricule = $userProvider->loadUserByUsername($authSso);

        if (!$matricule) {
            throw new CustomUserMessageAuthenticationException(
                sprintf('Matricule "%s" does not exist.', $authSso)
            );
        }

        $user = $userProvider->loadUserByUsername($matricule);

        return new PreAuthenticatedToken(
            $user,
            $authSso,
            $providerKey,
            $user->getRoles()
        );
    }
}

puis on le déclare dans app/services.yml

services:
    ...
    app.security.headerIndividuProvider:
        class: AppBundle\Security\SsoAuthenticator

et le tour est joué!

resource documentaire:

lemonLDAP avec Symfony:

identification avec le sso avec Symfony:

identification ldap avec Symfony:

2 en 1 avec Symfony:

Forum:

comprendre la sécurité sous Symfony 2.8:

connection avec un service exterieur:

Post précédent