2014-09-28 2 views
6

У меня есть логин для интерфейса (который является необязательным) и другой логин для панели администратора, что является обязательным.Symfony: несколько контекстов брандмауэра - пользователь пересылается в неправильный контекст

Когда пользователь переходит к fe_login, они могут войти в контекст frontend. Это нормально!

Когда они обращаются к admin_login, они должны иметь возможность входа в контекст admin. Это не хорошо

Вопрос заключается в том, что, когда я иду в /admin, я попадаю в fe_login, когда я должен быть перенаправлен на admin_login

Вот мой security.yml:

security: 
    encoders: 
     App\FrontendBundle\Controller\UserController: 
      algorithm: bcrypt 
     App\AdminBundle\Controller\UserController: 
      algorithm: bcrypt 
     App\Entity\User: 
      algorithm: bcrypt 
    providers: 
     administrators: 
      entity: { class: AppEntity:User, property: username } 

    firewalls: 
     dev: 
      pattern: ^/(_(profiler|wdt)|css|images|js)/ 
      security: false 
     admin: 
      pattern: ^/admin 
      form_login: 
       login_path: admin_login 
       check_path: admin_auth 
       csrf_provider: form.csrf_provider 
      logout: 
       path: admin_logout 
       target: admin_login 
     frontend: 
      anonymous: ~ 
      form_login: 
       login_path: fe_login 
       check_path: fe_auth 
       csrf_provider: form.csrf_provider 
       always_use_default_target_path: true 
       default_target_path: fe_landing 
      logout: 
       path: fe_logout 
       target: fe_landing 
     login: 
      pattern: ^/admin/login 
      anonymous: ~ 

     default: 
      anonymous: ~ 
    access_control: 
     - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/admin, roles: [ROLE_ADMIN,ROLE_MANAGER,ROLE_DRIVER,ROLE_PARTNER] } 

Любая идея, что я делаю неправильно?

ответ

2

Я не совсем уверен, что причина, но вы должны теперь security.yml должны быть очень ясно, файл, чтобы избежать конфигурации промаха (что привело бы в вопросах безопасности)

Таким образом, в отношении ваш файл:

  • мимо ключ шаблона на участке внешнего интерфейса: Я хотел бы добавить pattern: ^/
  • путь внешнего интерфейса Логин может быть определен, как вы делали для бэкэнда один
  • порядок ваших правил заставляют меня думать, что-то не правильно

Это версия вы должны проверить:

security: 
    encoders: 
     App\FrontendBundle\Controller\UserController: 
      algorithm: bcrypt 
     App\AdminBundle\Controller\UserController: 
      algorithm: bcrypt 
     App\Entity\User: 
      algorithm: bcrypt 

    providers: 
     administrators: 
      entity: { class: AppEntity:User, property: username } 

    firewalls: 
     dev: 
      pattern: ^/(_(profiler|wdt)|css|images|js)/ 
      security: false 
     login_admin: 
      pattern: ^/admin/login 
      anonymous: ~ 
     admin: 
      pattern: ^/admin 
      form_login: 
       login_path: admin_login 
       check_path: admin_auth 
       csrf_provider: form.csrf_provider 
      logout: 
       path: admin_logout 
       target: admin_login 
     login_frontend: 
      pattern: ^/login # you should adapt this to your app 
      anonymous: ~ 
     frontend: 
      pattern: ^/ 
      anonymous: ~ 
      form_login: 
       login_path: fe_login 
       check_path: fe_auth 
       csrf_provider: form.csrf_provider 
       always_use_default_target_path: true 
       default_target_path: fe_landing 
      logout: 
       path: fe_logout 
       target: fe_landing 

    access_control: 
     - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/admin, roles: [ROLE_ADMIN,ROLE_MANAGER,ROLE_DRIVER,ROLE_PARTNER] } 
+0

Согласитесь с этим, начните с чистого прототипа и проверьте после каждой модификации, чтобы вы могли обнаружить ошибку. – COil

+1

Я бы не рекомендовал использовать много брандмауэров. Нет необходимости иметь брандмауэр для каждой страницы входа. С гораздо меньшим количеством брандмауэров можно управлять гораздо проще, а также упростить устранение неполадок. – Sehael

3

Вот мой security.yml, но, как я уже сказал, это для Symfony2.0, может быть, вы найдете подсказку.

security: 
    encoders: 

### ... 

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

providers: 
    fos_userbundle: 
     id: fos_user.user_manager 
    admin_adminbundle: 
     id: custom_admin_manager_id 

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

    admin: 
     pattern: ^/admin/ 

     form_login: 
      check_path:   /admin/check-login 
      login_path:   /admin/login 
      provider:   admin_adminbundle 
      csrf_provider:  form.csrf_provider 
      post_only:   true 
      success_handler: login_success_handler 
      failure_handler: admin_login_failure_handler 
      username_parameter: login_username 
      password_parameter: login_password 
      remember_me:  false 
     logout: 
      path:    /admin/logout 
      target:    /admin/login 
     anonymous: true 

    frontend: 
     pattern: ^/ 

     form_login: 
      check_path:   /frontend/check-login 
      login_path:   /frontend/login 
      provider:   fos_userbundle 
      csrf_provider:  form.csrf_provider 
      post_only:   true 
      success_handler: login_success_handler 
      failure_handler: login_failure_handler 
      username_parameter: login_username 
      password_parameter: login_password 
     logout: 
      path:    /frontend/logout 
      success_handler: logout_success_handler 
     anonymous: true 

access_control: 
    - { path: ^/frontend/login$, role: IS_AUTHENTICATED_ANONYMOUSLY } 
    - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY } 
+0

Это приводит к циклу перенаправления на 'admin_login' – HyderA

+0

Вы нашли ошибку? У меня точно такая же настройка в одном из моих приложений, но для Symfony 2.0 и старый выпуск FOSUserBundle, поэтому я не уверен, что это вам поможет. – COil

+0

Пока нет. Но давайте посмотрим, поможет ли щедрость;) – HyderA

1

У вас есть несколько брандмауэров, которые кажутся ненужными. Давайте упростить конфигурации брандмауэра:

firewalls: 
    dev: 
     pattern: ^/(_(profiler|wdt)|css|images|js)/ 
     security: false 
    admin: 
     pattern: ^/admin 
     form_login: 
      login_path: admin_login 
      check_path: admin_auth 
      csrf_provider: form.csrf_provider 
     logout: 
      path: admin_logout 
      target: admin_login 
     anonymous: ~ 
    frontend: 
     pattern: ^/ 
     anonymous: ~ 
     form_login: 
      login_path: fe_login 
      check_path: fe_auth 
      csrf_provider: form.csrf_provider 
      always_use_default_target_path: true 
      default_target_path: fe_landing 
     logout: 
      path: fe_logout 
      target: fe_landing 

access_control: 
    # allow unauthenticated to access admin login 
    - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
    # restrict admin access 
    - { path: ^/admin, roles: [ROLE_ADMIN,ROLE_MANAGER,ROLE_DRIVER,ROLE_PARTNER] } 
    # allow unauthenticated to access front end login 
    - { path: ^/fe/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
    # restrict front end access 
    - { path: ^/fe, roles: ROLE_USER } # or whatever the role is of your frontend user 
    # allow all other pages to be viewed by unauthenticated users 
    - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY } 

Эта конфигурация делает это так, чтобы все страницы под /fe требуют передний конец разрешения и все страницы под /admin требуют разрешения администратора. И все остальные страницы не защищены вообще. Вы можете настроить это, как хотите.

Важным является порядок доступа. Как только правило будет согласовано, оно не будет пытаться сопоставить любые другие записи. Эта конфигурация должна работать так, чтобы отображался правильный логин. Однако, похоже, что вы используете другой поставщик услуг для каждого брандмауэра. Поэтому, когда вы входите в систему, приложение будет использовать один и тот же провайдер для обоих входов. Это может быть или не быть тем, что вы намереваетесь, но я думал, что хочу указать на это. Если вам нужен другой пользовательский провайдер для каждого входа, просто добавьте provider: ProviderName к каждому брандмауэру.

Смежные вопросы