SSO + FOSUserBundle sous Symfony 3

sso--fosuserbundle-sous-symfony-3



1 121 vues

Je vais vous montrer en quelques lignes comment mettre en place une connexion par SSO basique couplée à FOSUserBundle très simplement et rapidement.

 

A vous de sécuriser au mieux votre architecture ;-)


Le principe d'un Single Sign-On repose sur l'accès/la connexion via une URL à une application/interface.

 

Dans l'idée, c'est de pouvoir se connecter via une authentification unique.

 

Qui dit URL, dit route...et questionnement sur l'accès...
Qui dit route, dit également un controller derrière.

 

Nous allons donc commencer par bien configurer et récupérer le nom de votre firewalls principal, main :

# app/config/security.yml
security:
    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt

    role_hierarchy:
        # [...]

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email

    firewalls:
        # [...]
        main:
            # [...]

    access_control:
        - { path: ^/sso/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        # [...]

 

Puis nous allons définir la route :

# app/config/routing.yml
# SSO
sso:
    path: /sso/{username}
    defaults: { _controller: YourBundle:SSO:connect, username: username }

Puis nous allons créer notre controller uniquement dédié au SSO.

Nous allons le faire en 4 étapes

  1. Dans un premier temps vérifer que l'utilisateur existe en base
  2. Etablir la connexion
  3. Informer aux events qu'un utilisateur s'est connecté
  4. Faire une redirection vers une page souhaitée via la route
// YourBundle/Controller/SSOController.php

namespace YourBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

class SSOController extends Controller
{
    public function connectAction(Request $request, $username)
    {
        // Initializing Entity Manager
        $em = $this->getDoctrine()->getManager();

        // Get user
        $user = $em->getRepository("YourBundle:User")->findOneBy(['username' => $username]);

        if ($user) {
            // Ici, on va connecter l'utilisateur ! :)
            $token = new UsernamePasswordToken($user, null, "main", $user->getRoles());
            $this->get("security.token_storage")->setToken($token);

            // On informe qu'une connexion vien d'avoir lieu aux events.
            $event = new InteractiveLoginEvent($request, $token);
            $this->get("event_dispatcher")->dispatch("security.interactive_login", $event);

            // Un redirection vers la route "homepage"
            return $this->redirect($this->generateUrl('homepage'));
        } else {
            throw $this->createNotFoundException();
        }
    }
}

Et voila, terminado !

A vous la connexion par SSO ! La classe non ? cool