Sécurisation API REST avec FOSUserBundle

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Je souhaite pouvoir m’authentifier sur un site utilisant symfony par une application mobile (ios ou Android). J’utilise FOSUserBundle pour gérer mes utilisateurs et sécurisé l’accès au site.

Pour l’échange de données entre le site et le mobile j’utilise donc une api rest basé sur le tutorial ’créez une api rest avec symfony 3’ de BestCoder qui est d’ailleurs très bien réalisé, les routes sont préfixés par /mobile.

Par contre le système d’authentification diffère un peu du tutorial car je ne vois pas du tout comment je peux faire pour créer un token et à quelle méthode fournir le login et password pour l’authentification.

Auriez-vous quelques pistes où avez-vous déjà réussi à le faire à tout hasard.

Merci d’avance pour votre aide et explication.

Salut,

J’utilise FOSUserBundle pour gérer mes utilisateurs et sécurisé l’accès au site.

FOSUserBundle ne gère pas l’authentification Symfony. Au mieux, le user provider qu’il fournit est branché au système d’authentification de Symfony.

Par contre le système d’authentification diffère un peu du tutorial car je ne vois pas du tout comment je peux faire pour créer un token et à quelle méthode fournir le login et password pour l’authentification.

Quel est le système d’authentification que tu as actuellement ? Avec Symfony, il est possible d’avoir plusieurs systèmes d’authentification actif en même temps. Tu peux avoir un firewall qui gère toutes les url commençant par /mobile et utiliser exactement le même système d’authentification présenter dans le cours.

Bonjour, merci pour votre temps.

FOSUserBundle ne gère pas l’authentification Symfony.

Désolé je ne comprends pas votre réponse car dans mon cas je n’ai pas eu à surcharger le contrôleur du bundle qui s’occupe de cette partie.

Au mieux, le user provider qu’il fournit est branché au système d’authentification de Symfony.

Oui effectivement j’utilise le user provider de FOSUserBundle pour stocker les données des utilisateurs, il gère en outre la page de login pour moi.

Quel est le système d’authentification que tu as actuellement ?

Voici mon fichier security.yml

 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
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html
security:

    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt
        SON\ApiBundle\Entity\UserApi:
            algorithm: bcrypt
            cost: 12

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER,ROLE_ADMIN]

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username
        auth_token_user_provider:
            id: auth_token_user_provider

    firewalls:

        api:
            pattern: ^/api
            # la conf pour l'api
            stateless: true
            simple_preauth:
                authenticator: auth_token_authenticator
            provider: auth_token_user_provider
            anonymous: ~

      # mobile:
      #     pattern: ^/mobile
           # la conf pour le mobile
      #     stateless: true
      #     provider: fos_userbundle
      #     csrf_token_generator: security.csrf.token_manager
      #     .
      #     .
      #     .
      #     anonymous: ~

        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js|default)/
            security: false


        main:
            pattern: ^/
            # la conf pour le reste de l'application
            form_login:
                provider: fos_userbundle
                csrf_token_generator: security.csrf.token_manager
                login_path: fos_user_security_login
                check_path: fos_user_security_check
                success_handler: son_user.login_handler
                failure_handler: son_user.login_handler
            remember_me:
                secret:   '%secret%'
                lifetime: 604800
                path:     /
            logout:       true
            anonymous:    true

        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, role: ROLE_ADMIN }
        - { path: ^/ban, role: ROLE_ADMIN }
        - { path: ^/profile, role: ROLE_USER }





`
+0 -0

Désolé je ne comprends pas votre réponse car dans mon cas je n’ai pas eu à surcharger le contrôleur du bundle qui s’occupe de cette partie.

La plupart des documentations sur FOSUserBundle induisent en erreur les lecteurs. FOSUserBundle ne gère pas la sécurité de ton application. C’est le form_login (propre à Symfony) qui s’occupe de cela. Le controleur SecurityController de FOSUSerBundle n’est là que pour faciliter la tâche aux développeurs en affichant un formulaire avec les champs login et password (fos_user_security_login) et en fournissant la liste des utilisateurs à Symfony.

La route fos_user_security_check ne sert qu’à fournir une url vers laquelle le formulaire de connexion sera envoyé. Symfony interceptera automatiquement toutes les requêtes vers cette url et s’occupera d’authentifier ou nom l’utilisateur. (Voir la documentation officielle)

D’ailleurs le code de l’action fos_user_security_check se contente de lever une execption si jamais s’est appelé en direct. (Voir le code source de FOSUserBundle)

En résumé, FOSUserBundle ne gère pas l’authentification Symfony. Tu peux t’en passer facilement si tu comprends bien comment il s’interface avec le système de sécurité de Symfony.

Par contre, dans la configuration que tu as postée, je ne vois pas qu’est-ce qui ne fonctionne pas. Qu’est-ce que tu as implémenté, etc.

Essayes de voir d’abord le fonctionnement du système de sécurité de Symfony et ce que tu veux faire te paraîtra comme une évidence. (Voir la documentation officielle qui a servi dans le cours)

Merci pour toutes ces explications, en effet mes connaissances dans le domaine son encore très limité.

Par contre, dans la configuration que tu as postée, je ne vois pas qu’est-ce qui ne fonctionne pas. Qu’est-ce que tu as implémenté, etc.

Justement rien car je ne sais pas par où commencé, c’était juste pour vous montrer ma configuration actuelle, les routes /mobile ne bénéficient d’aucune authentification pour l’instant.

Essayes de voir d’abord le fonctionnement du système de sécurité de Symfony et ce que tu veux faire te paraîtra comme une évidence. (Voir la documentation officielle qui a servi dans le cours)

Très bien je vais commencer par là, merci pour cette piste.

Bonjour,

Je reviens vers vous car j’ai effectivement réussi à produire un token et créer un utilisateur du site géré avec FOSUSERBUNDLE avec des appels api.

Par contre je n’arrive pas à protéger l’accès des routes préfixé avec /mobile correctement car mauvaise configuration de mon security.yml et services.yml Voici donc mes fichier

security.yml

 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
security:

    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt
        SON\ApiBundle\Entity\UserApi:
            algorithm: bcrypt
            cost: 12

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER,ROLE_ADMIN]

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username
        auth_token_user_provider:
            id: auth_token_user_provider
            ### Ligne rajouter pour le mobile 
        auth_token_user_provider_m:
            id: auth_token_user_provider_m

    firewalls:

        api:
            pattern: ^/api
            # la conf pour l'api
            stateless: true
            simple_preauth:
                authenticator: auth_token_authenticator
            provider: auth_token_user_provider_m
            anonymous: ~

      mobile:
          pattern: ^/mobile
          # la conf pour le mobile 
          stateless: true
          simple_preauth:
              authenticator: auth_token_authenticator
          provider: auth_token_user_provider
          anonymous: ~

        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js|default)/
            security: false


        main:
            pattern: ^/
            # la conf pour le reste de l'application
            form_login:
                provider: fos_userbundle
                csrf_token_generator: security.csrf.token_manager
                login_path: fos_user_security_login
                check_path: fos_user_security_check
                success_handler: son_user.login_handler
                failure_handler: son_user.login_handler
            remember_me:
                secret:   '%secret%'
                lifetime: 604800
                path:     /
            logout:       true
            anonymous:    true

        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, role: ROLE_ADMIN }
        - { path: ^/ban, role: ROLE_ADMIN }
        - { path: ^/profile, role: ROLE_USER }

service.yml

 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
services:
    get_set_method_normalizer:
        class: Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer
        public: false
        tags:
            - { name: serializer.normalizer }

    auth_token_user_provider:
        class: SON\ApiBundle\Security\AuthTokenUserProvider
        arguments: ["@auth_token_repository", "@user_repository"]
        public:    false

    auth_token_repository:
        class:   Doctrine\ORM\EntityManager
        factory: ["@doctrine.orm.entity_manager", "getRepository"]
        arguments: ["SONApiBundle:AuthToken"]

    user_repository:
        class:   Doctrine\ORM\EntityManager
        factory: ["@doctrine.orm.entity_manager", "getRepository"]
        arguments: ["SONApiBundle:UserApi"]

    auth_token_authenticator:
        class:     SON\ApiBundle\Security\AuthTokenAuthenticator
        arguments: ["@security.http_utils"]
        public:    false
 ##   Ici les lignes que j'ai rajouté               @##############

  auth_token_user_provider_m:
      class: SON\ApiBundle\Security\AuthTokenUserProvider
      arguments: ["@auth_token_repository_m", "@user_repository_m"]
      public:    false

  auth_token_repository_m:
      class:   Doctrine\ORM\EntityManager
      factory: ["@doctrine.orm.entity_manager", "getRepository"]
      arguments: ["SONApiBundle:AuthTokenM"]

  user_repository_m:
      class:   Doctrine\ORM\EntityManager
      factory: ["@doctrine.orm.entity_manager", "getRepository"]
      arguments: ["SONUserBundle:Utilisateur"]

`

config.yml j’ai rajouter une zone pour le mobile, voici ma configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
fos_rest:
    serializer:
        serialize_null:  true
    routing_loader:
        include_format: false
    view:
        view_response_listener: true
    format_listener:
        rules:
            - { path: '^/', priorities: ['json'], fallback_format: 'json' }
    exception:
        enabled: true
        messages:
            'Symfony\Component\Security\Core\Exception\BadCredentialsException': true
            'Symfony\Component\HttpKernel\Exception\HttpException' : true
        codes:
            'Symfony\Component\Security\Core\Exception\BadCredentialsException': 401
    zone:
        - { path: ^/api }
        - { path: ^/mobile }

Merci beaucoup pour votre aide.

+0 -0

Qu’est ce que tu as comme message d’erreur ?

Ton poste contient trop d’informations pour que qu’on puisse t’aider efficacement.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
        api:
            pattern: ^/api
            # la conf pour l'api
            stateless: true
            simple_preauth:
                authenticator: auth_token_authenticator
            provider: auth_token_user_provider_m
            anonymous: ~

      mobile:
          pattern: ^/mobile
          # la conf pour le mobile 
          stateless: true
          simple_preauth:
              authenticator: auth_token_authenticator
          provider: auth_token_user_provider
          anonymous: ~

Dans cet extrait de code, le provider auth_token_user_provider_m semble être inversé avec le provider auth_token_user_provider non ?

Merci pour votre réponse,

bien vu mais c’est juste un mauvais screen de ma part dsl, sinon le message d’erreur dit tout simplement :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
The file "../www/Symfony/app/config/security.yml" does not contain valid YAML in ../Symfony/app/config/security.yml (which is being imported from "../Symfony/app/config/config.yml").

AUSSI 

The file ".../app/config/security.yml" does not contain valid YAML.

En FIN

ParseException in Parser.php line 483:
Indentation problem at line 66 (near " mobile:").

Je précise que mes utilisateurs du site/mobile son don le SON/HomeBundle/Entity/Utilisateur donc voici mon security.yml actuelle :

 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
security:

    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt
        SON\ApiBundle\Entity\UserApi:
            algorithm: bcrypt
            cost: 12

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER,ROLE_ADMIN]

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username
        auth_token_user_provider:
            id: auth_token_user_provider
        auth_token_user_provider_m:
            id: auth_token_user_provider_m


    firewalls:

        api:
            pattern: ^/api
            # la conf pour l'api
            stateless: true
            simple_preauth:
                authenticator: auth_token_authenticator
            provider: auth_token_user_provider
            anonymous: ~

         mobile:
            pattern: ^/mobile
            # la conf pour le mobile
            stateless: true
            simple_preauth:
                authenticator: auth_token_authenticator
            provider: auth_token_user_provider_m
            anonymous: ~

        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js|default)/
            security: false


        doc:
            pattern: ^/documentation
            security: false

        main:
            pattern: ^/
            # la conf pour le reste de l'application
            form_login:
                provider: fos_userbundle
                csrf_token_generator: security.csrf.token_manager
                login_path: fos_user_security_login
                check_path: fos_user_security_check
                success_handler: son_user.login_handler
                failure_handler: son_user.login_handler
            remember_me:
                secret:   '%secret%'
                lifetime: 604800
                path:     /
            logout:       true
            anonymous:    true

        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, role: ROLE_ADMIN }
        - { path: ^/ban, role: ROLE_ADMIN }
        - { path: ^/profile, role: ROLE_USER }

Je peux afficher une partie des logs si ça peut aider. Si besoin d’autre chose dites moi car la je suis vraiment bloqué !

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte