CAS Authentication Symfony2

前端 未结 2 1361
逝去的感伤
逝去的感伤 2021-02-08 23:49

I\'m looking for a bundle to integrate CAS authentication on Symfony 2.3. I found these options and the truth is I\'m not convinced any, since almost all bundles seem to be aban

相关标签:
2条回答
  • 2021-02-09 00:02

    I have the same issue before and i resolved it using BeSimpleSsoAuthBundle but you have to make a few changes : Supposed that you have your user entity has been already implemented in your UserBundle, with a unique attribute sgid you have to override : 1- BeSimple\SsoAuthBundle\Security\Core\User :

    <?php
    
    namespace Application\UserBundle\Security\BeSimple\SpawnedUserProvider;
    
    use BeSimple\SsoAuthBundle\Security\Core\User\SpawnedUserProvider;
    use Symfony\Component\Security\Core\User\UserInterface;
    use Symfony\Component\Security\Core\User\User;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    
    
    class SsoUserProvider extends SpawnedUserProvider
    {
    /**
     * @var array
     */
    private $roles;
    
    /**
     * Constructor.
     *
     * @param array $roles An array of roles
     */
    private $entityManager;
    private $securityContext;
    
    public function __construct($em, $securityContext) {
        $this->em = $em; 
        $this->securityContext = $securityContext; 
    }
    
    /**
     * {@inheritdoc}
     */
    public function loadUserByUsername($username)
    {
        $session = $this->securityContext;
    
        $qb = $this->em->createQueryBuilder();
        $qb->select("u")
            ->from('ApplicationUserBundle:User', 'u')
            ->where('u.sgid = :sgid')
            ->AndWhere('u.status = 1')
            ->setParameter("sgid", $username);
    
       $result = $qb->getQuery()->getOneOrNullResult();
    
        if ($result == NULL) {
            $session->getFlashBag()->add('error', 'Vous ne pouvez pas vous connecter car votre compte est désactivé');
            return new RedirectResponse('login');
        }
    
       $user_name = $result->getFirstName().' '.$result->getLastName();
        $session->set('userId', $result->getId());
       if ($result->getUserType() == 1) {
           $this->roles = array('ROLE_ADMIN');
       }else if ($result->getUserType() == 0){
           $this->roles = array('ROLE_USER');
       }else{
            $session->getFlashBag()->add('error', 'Vous ne pouvez pas vous connecter car votre compte n\'a pas de rôle');
            return new RedirectResponse('logout');
       }
        return $this->spawnUser($user_name);
    }
    
    /**
     * {@inheritDoc}
     */
    public function refreshUser(UserInterface $user)
    {
        if (!$user instanceof User) {
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
        }
    
        return $this->spawnUser($user->getUsername());
    }
    
    /**
     * {@inheritDoc}
     */
    public function supportsClass($class)
    {
        return $class === 'Symfony\Component\Security\Core\User\User';
    }
    
    /**
     * Spawns a new user with given username.
     *
     * @param string $username
     *
     * @return \Symfony\Component\Security\Core\User\User
     */
    private function spawnUser($username)
    {
        //$this->roles = $this->userType;
        return new User($username, null, (array)$this->roles, true, true, true, true);
      }
    }
    

    2- Override also BeSimple\SsoAuthBundle\Security\Core\Authentication\Provider :

    <?php
    
    namespace Application\UserBundle\Security\BeSimple\Authentication\Provider;
    
    use Symfony\Component\Security\Core\User\UserInterface;
    use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
    use Symfony\Component\Security\Core\Exception\BadCredentialsException;
    use BeSimple\SsoAuthBundle\Security\Core\User\UserFactoryInterface;
    
    /*
     * @Override 
     */
    use    BeSimple\SsoAuthBundle\Security\Core\Authentication\Provider\SsoAuthenticationPr ovider;
    
    class AppAuthenticationProvider extends SsoAuthenticationProvider
    {
    /**
     * @var UserProviderInterface
     */
    private $userProvider;
    
    /**
     * @var bool
     */
    private $createUsers;
    
    /**
     * @var bool
     */
    private $hideUserNotFound;
    
    /**
     * @Override file
     * @throws \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
     * @throws \Symfony\Component\Security\Core\Exception\BadCredentialsException
     *
     * @param string $username
     * @param array $attributes
     *
     * @return UserInterface
     */
    protected function provideUser($username, array $attributes = array())
    {
        try {
            $user = $this->retrieveUser($username);
        } catch (UsernameNotFoundException $notFound) {
            if ($this->createUsers && $this->userProvider instanceof UserFactoryInterface) {
                $user = $this->createUser($username, $attributes);
            } elseif ($this->hideUserNotFound) {
                throw new BadCredentialsException('Bad credentials', 0, $notFound);
            } else {
                throw $notFound;
            }
        }
    
        return $user;
      }
    
    }
    

    3- When user login to your application save needed information in session :

    <?php
    
    namespace Application\UserBundle\Security\Authentication\Handler;
    
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\Routing\Router;
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\Security\Core\SecurityContext;
    use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
    use Doctrine\ORM\EntityManager;
    
    class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
    {
    protected 
        $router,
        $security,
        $entityManager;
    
    public function __construct(Router $router, SecurityContext $security, EntityManager $entityManager)
    {
        $this->router = $router;
        $this->security = $security;
        $this->entityManager = $entityManager;
    }
    
    public function onAuthenticationSuccess(Request $request, TokenInterface $token)
    {
        $session = $request->getSession();
    
        $attributes = $this->security->getToken()->getAttributes();
        $sgid = $attributes['sso:validation']['sgid'];
    
        $em = $this->entityManager;
        $qb = $em->createQueryBuilder();
        $qb->select("u")
            ->from('ApplicationUserBundle:User', 'u')
            ->where('u.sgid = :sgid')
            ->AndWhere('u.status = 1')
            ->setParameter("sgid", $sgid);
    
        $result = $qb->getQuery()->getOneOrNullResult();
    
        //en cas où utilisateur est désactivée
        //Malgre que si il arrive a cette handler ça veut dire qu'il activé car le test se fait sur le bundle BeSimple
        if ($result == NULL) {
            return new RedirectResponse($this->router->generate('login'));
        }
    
        $session->set('userId', $result->getId());
    
        $response = new RedirectResponse('admin');
    
        return $response;
      }
    }
    

    4- Now define a security listner in Application/UserBundle/Ressources/config/security_listeners.yml :

    parameters:
        security.authentication.provider.sso.class: Application\UserBundle\Security\BeSimple\Authentication\Provider\AppAuthenticationProvider
    
    services:
        security.authentication.provider.sso:
            class: %security.authentication.provider.sso.class%
            public: false
            arguments: ['', '@security.user_checker', '', '', false]
    

    5- The BeSimple configuration should be like that :

    be_simple_sso_auth:
    admin_sso:
        protocol:
            id: cas
            version: 2
        server:
            id: cas
            login_url: https://adresse ip:8443/cas-server-webapp-4.0.0/login
            logout_url: https://adresse ip:8443/cas-server-webapp-4.0.0/logout
            validation_url: https://adresse ip:8443/cas-server-webapp-4.0.0/serviceValidate
    services:
    
        spawned_user_provider:
            class:     Application\UserBundle\Security\BeSimple\SpawnedUserProvider\SsoUserProvider
        arguments: [@doctrine.orm.entity_manager, @session]
    

    6- The parameters.yml

      be_simple.sso_auth.client.option.curlopt_ssl_verifypeer.value: false
      be_simple.sso_auth.client.option.curlopt_sslversion.value: 4 (Optionale)
    

    7- The security.yml

      main:
            pattern: ^/admin
            context: marketshare_context
            logout:
                path:   /admin/logout
                target: /
            #provider: sso
            trusted_sso:
                manager: admin_sso
                login_action: ApplicationUserBundle:TrustedSso:login
                logout_action: false
                login_path: /admin/login
                check_path: /admin/check
                always_use_default_target_path: true
                default_target_path: /admin/potentiel
                failure_path: /admin/logout
    
    0 讨论(0)
  • 2021-02-09 00:12

    You can also test l3-team/CasBundle it seems more recent & active and with a clearer documentation than BeSimpleSSoBundle.

    It also seems to support Single Sign Out.

    0 讨论(0)
提交回复
热议问题