IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Utiliser guard Symfony avec multiple provider


Sujet :

Symfony PHP

  1. #1
    Membre du Club
    Homme Profil pro
    .
    Inscrit en
    Avril 2016
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2016
    Messages : 108
    Points : 49
    Points
    49
    Par défaut Utiliser guard Symfony avec multiple provider
    Bonjour à tous,

    Je réalise une API Rest sous symfony, et je suis maintenant sur la partie Utilisteur/Sécurité et me retrouve face à un problème.

    Pour l'identification des utilisateurs nous demandons de s'authentifier par facebook ou google. Nous utilisons le protocole Oauth2 pour faire cela.
    Donc au niveau du fonctionnement, sur la partie Client ( pour l'instant app Android et site sous angular ) :

    - L'utilisateur choisit sur quel réseau social il veut se connecter
    - L'utilisateur est ensuite redirigé sur la page d'autorisation et doit autoriser notre application à accéder à ses données.
    - Une fois l'autorisation obtenu, il est redirigé sur le client avec un code permettant l'échange contre un access_token.
    - A partir de la l'utilisateur est considéré comme connecté sur la partie client.

    Maintenant l'utilisateur va faire une action qui demande de contacter mon API , il faut que le client envoie dans le header de la requete un Bearer correspondant à l'access_token.
    Du coté de l'API, j'ai fait un guard protégeant certaines routes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            oauth:
                pattern:   ^/
                stateless: true
                simple_preauth:
                   authenticator: Oauth_authenticator
                provider: provider.google_user
    Je n'ai pas de problème pour récupérer les infos de l'utilisateur et pouvoir l'authentifier sur l'api, mon problème est comme vous le voyez, que j'injecte pour le moment directement mon provider de Google, alors qu'il me faut utiliser soit le provider de google soit celui de Facebook.
    La seule doc de symfony la dessus ne m'a pas vraiment avancé : https://symfony.com/doc/3.4/security...nticators.html

    Ma question est de savoir si quelqu’un à déjà eu ce problème et quelle est la bonne stratégie à adapter ? Faut il plusieurs authenticator liées chacun à un provider spécialement ? Ou un seul aunthenticor qui utilise deux providers ? Je n'arrive pas à comprendre comment faire pour qu'a la reception de la requete mon guard récupere le bon service associé ?

    Je vous met mon authenticator et provider pour vous montrer ce que je fais pour le moment :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    class OauthAuthenticator implements SimplePreAuthenticatorInterface,AuthenticationFailureHandlerInterface
    {
     
        private $userProvider;
     
        function __construct(UserProviderInterface $userProvider)
        {
            $this->userProvider = $userProvider;
     
        }
     
        public function createToken(Request $request, $providerKey)
        {
     
            $bearer = $request->headers->get('Authorization');
     
            $accessToken = substr($bearer, 7);
     
     
            return new PreAuthenticatedToken(
     
                'anon.',
     
                $accessToken,
     
                $providerKey
     
            );
        }
     
        public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
        {
            $accessToken = $token->getCredentials();
     
     
     
     
            $user = $userProvider->loadUserByUsername($accessToken);
     
     
            return new PreAuthenticatedToken(
                $user,
                $accessToken,
                $providerKey,
                ['ROLE_USER']
            );
        }
     
        /**
         * This is called when an interactive authentication attempt fails. This is
         * called by authentication listeners inheriting from
         * AbstractAuthenticationListener.
         *
         * @return Response The response to return, never null
         */
        public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
        {
            return new Response("Authentication Failed ", 401);
        }
     
     
     
        public function supportsToken(TokenInterface $token, $providerKey)
        {
            return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
        }
     
     
     
     
        /**
         * @return UserProviderInterface
         */
        public function getUserProvider(): UserProviderInterface
        {
            return $this->userProvider;
        }
     
        /**
         * @param UserProviderInterface $userProvider
         */
        public function setUserProvider(UserProviderInterface $userProvider)
        {
            $this->userProvider = $userProvider;
        }
    GoogleProvider:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    class GoogleProvider implements UserProviderInterface
    {
        private $client;
        private $serializer;
        private $router;
        private $userManager;
     
     
     
        function __construct(Client $client,Serializer $serializer,Router $router,UserManagerInterface $userManager)
        {
            $this->client = $client;
            $this->serializer = $serializer;
            $this->router = $router;
            $this->userManager = $userManager;
     
        }
     
     
        /**
         * Loads the user for the given username.
         *
         * This method must throw UsernameNotFoundException if the user is not
         * found.
         *
         * @param string $username The username
         *
         * @return UserInterface
         *
         * @throws UsernameNotFoundException if the user is not found
         */
        public function loadUserByUsername($username)
        {
     
     
            $url = 'https://www.googleapis.com/oauth2/v1/userinfo?access_token='.$username;
     
    //        dump($url);die();
            try{
                $response = $this->client->get($url);
            }catch (Exception $exception){
                throw new \Exception($exception->getMessage(),404);
            }
     
     
            $res = $response->getBody()->getContents();
           // dump(json_decode($res));
     
     
            $userData = $this->serializer->deserialize($res,'array','json');
     
            // dump($userData);die();
     
            if (!$userData){
                throw new LogicException('Did not managed to get your user info from social network');
            }
     
            $existingUser = $this->userManager->getUserByGoogleAccount($userData['id']) ;
     
     
            if ($existingUser != null){
                /** @var \AppBundle\Entity\Interfaces\UserInterface $existingUser */
                $existingUser->setEmail($userData['email']);
                $existingUser->setGoogleId($userData['id']);
                $existingUser->setFullname($userData['name']);
                //dump($existingUser );
     
                return $existingUser;
            }
     
            $user = new User();
     
            $user->setEmail($userData['email']);
            $user->setGoogleId($userData['id']);
            $user->setFullname($userData['name']);
     
    //        dump($user);
     
     
             $user = $this->userManager->createUser($user);
    //        dump($user);die();
            return $user;
     
            // TODO: Implement loadUserByUsername() method.
        }
     
        /**
         * Refreshes the user.
         *
         * It is up to the implementation to decide if the user data should be
         * totally reloaded (e.g. from the database), or if the UserInterface
         * object can just be merged into some internal array of users / identity
         * map.
         *
         * @return UserInterface
         *
         * @throws UnsupportedUserException if the user is not supported
         */
        public function refreshUser(UserInterface $user)
        {
            $class = get_class($user);
     
            if (!$this->supportsClass($class)){
                throw new \Symfony\Component\Security\Core\Exception\UnsupportedUserException();
            }
     
            return $user;// TODO: Implement refreshUser() method.
        }
     
        /**
         * Whether this provider supports the given user class.
         *
         * @param string $class
         *
         * @return bool
         */
        public function supportsClass($class)
        {
            // TODO: Implement supportsClass() method.
            return 'AppBundle\Entity\User' === $class;
        }
    }

    Je dois passer mon diplome bientot et j'aimerai vraiment implémenter cette fonctionnalité , alors tout les retours seront vraiment les bienvenus !

    Un grand merci à vous,

    Cordialement,

  2. #2
    Membre du Club
    Homme Profil pro
    .
    Inscrit en
    Avril 2016
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2016
    Messages : 108
    Points : 49
    Points
    49
    Par défaut
    Personne n'est passé par la ??

Discussions similaires

  1. Réponses: 2
    Dernier message: 29/11/2017, 09h01
  2. [3.x] Utilisation de CORS avec un back Symfony
    Par asaleth dans le forum Symfony
    Réponses: 2
    Dernier message: 20/11/2016, 16h54
  3. [2.x] Utilisation de Css3PIE avec symfony
    Par itokia dans le forum Symfony
    Réponses: 2
    Dernier message: 21/02/2013, 09h23
  4. utilisation de dll avec diverses compilateurs
    Par Thylia dans le forum C++
    Réponses: 30
    Dernier message: 21/10/2004, 16h30
  5. Utiliser Borland C++ avec Emacs sous Windows
    Par Eikichi dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 02/03/2003, 08h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo