2015-03-13 4 views
0

У меня есть приложение Symfony2, разделенное на 2 пакета: BackendBundle для API и FrontendBundle для AngularJS «клиент». Все работает под брандмауэром.Symfony2: разрешить доступ ко всем непревзойденным маршрутам анонимно

BackendBundle имеет сущности, обрабатывает маршруты API; FrontendBundle имеет угловые виды, маршрутизацию и т.д., и имеет только один контроллер с шаблоном:

class AngularController extends Controller { 
    /** 
    * @Route("/{route}", name="angular_index_all_unmatched_routes", requirements={"route" = ".*"}) 
    * @Template("FrontendBundle::index.html.twig") 
    */ 
    public function angularIndexAction($route) { 
     return ['route' => $route]; 
    } 
} 

FrontendBundle маршрутизация определяются как последний ресурс в app/config/routing.yml, который будет вызвана только тогда, когда любой другой маршрут не был подобран. Благодаря этому он может обрабатывать маршруты с угловым HTML5-режимом, если к ним обращаются напрямую (например, copy-paste) - и он работает нормально.

То, что я хочу сделать, это определить межсетевой экран и/или контроль доступа в таким образом, что все эти несогласованные маршруты (обрабатываются AngularController::angularIndexAction()) может быть доступен анонимным пользователем.

Почему? Я хочу открыть некоторые маршруты API (через frontend proxy), чтобы они были доступны не пользователям (например, URL-адреса подтверждения, отправленные по электронной почте, с некоторым сообщением пользователю).

Я не хочу указывать список контроля доступа для каждого анонимного «Углового» маршрута, я хотел бы сделать это только для маршрутов API. В конце концов, эти непревзойденные маршруты должны открывать индекс Angular, который должен знать, если пользователь вошел в систему (для отображения полного или упрощенного макета) и должен обрабатывать угловые маршруты и отображать какое-то сообщение «Access denied», если запрос не выполнен (есть слушатель Symfony и перехватчик Angle's $provide).

Любые предложения?


Edit: @Security аннотацию на AngularController::angularIndexAction() не работает, он по-прежнему перенаправляет на брандмауэр точку входа.


Edit2:. Вот фрагмент security.yml

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

    secured: 
     pattern: '^.*$' 
     form_login: 
      login_path: /our-provider/login 
      check_path: /our-provider/callback/ 
     anonymous: true 
     entry_point: our_provider.entry_point 

access_control: 
    - { path: '^/our-provider/(login(/[a-zA-Z]+)?|logout|redirect|callback)', roles: IS_AUTHENTICATED_ANONYMOUSLY } 
    - { path: '^/', roles: ROLE_USER } 

Я знаю, что { path: '^/', roles: ROLE_USER } будет перенаправлять все маршруты на страницу входа, если пользователь не вошел в систему, я предположил, что это очевидно и не упомянул об этом , Я хочу, чтобы сила ROLE_USER для соответствовала маршрутам и давала IS_AUTHENTICATED_ANONYMOUSLY для тех, кто не имеет себе равных, без четкого определения каждого интерфейса «прокси-маршрут». В моем случае нет страницы 404 Symfony, потому что все идет по маршруту angular_index_all_unmatched_routes, и там определение угловой маршрутизации решает, есть ли что-то для обработки или нет.

+0

Есть ли у вас какие-либо другие маршруты помимо '^ /', которые не предназначены для анонимности? –

+0

Да, все '^/api /' например.На данный момент API с «псевдоавторией», поскольку он основан на одном и том же брандмауэре от безопасности Symfony. Таким образом, в основном пользователь должен войти в приложение для использования API (потому что это только для связи с внешним интерфейсом прямо сейчас, оно будет изменено, если мы откроем API для других клиентов). Таким образом, брандмауэр настроен на '' ^. * $ 'Для автоматического перенаправления на страницу входа для анонимных пользователей. Итак, подведем итог: используйте брандмауэр для существующих маршрутов Symfony, разрешите анонимный доступ для угловых маршрутов, обработанных 'AngularController :: angularIndexAction()'. – Wirone

+0

DId, вы получите это, чтобы работать? –

ответ

0

Я не пробовал это, и я не могу угадать вашу существующую настройку безопасности/маршрута в security.yml, но я думаю, вы могли бы использовать белый список метода с помощью IS_AUTHENTICATED_ANONYMOUSLY. Из Symfony docs:

Все пользователи (даже анонимные) есть это - это полезно, когда белый список URL-адресов для обеспечения доступа - некоторые детали в How Does the Security access_control Work?.

Так, например, если вы использовали @Security аннотацию вы могли бы сделать что-то подобное (не проверено):

class AngularController extends Controller { 
    /** 
    * @Route("/{route}", name="route", requirements={"route" = ".*"}) 
    * @Template("FrontendBundle::index.html.twig") 
    * @Security("has_role('IS_AUTHENTICATED_ANONYMOUSLY')") 
    */ 
    public function angularIndexAction($route) { 
     return ['route' => $route]; 
    } 
} 

Больше на @Security аннотацию here.

Надеется, что это помогает :)

Редактировать

Все, что сказал, когда вы определяете/ограничить маршруты под access_control в security.yml, процесс согласования останавливается на первый матче. Я предполагаю, что у вас есть некоторые ограничения, ограниченные ролями, которые вы должны явно определить - и сначала поместите их, поэтому, если они совпадают с остановками процесса.

В противном случае вы должны будете иметь возможность добавить маршрут общего маршрута, принудительно выполняемый ролью IS_AUTHENTICATED_ANONYMOUSLY. Поскольку определение маршрута маршрута является регулярным выражением, что-то вроде ^/ должно ловить все, что явно не определено. Просто убедитесь и поместите его после ваших ограниченных определений маршрута.

Аннотации @Security в этом случае вам не понадобятся.

Edit 2

Я попытался насмешливый это, используя чистый экземпляр и HTTP BasicAuth, но то, что я пытался достичь было следующее, что я понимаю, как похожий на ваш прецеденту:

  • Создайте backend-контроллер с маршрутами / и /api/ и вызовите HTTP-аутентификацию по умолчанию BasicAuth.
  • Создайте внешний контроллер с маршрутом /{route}, который будет соответствовать каждому g else и аутентифицировать анонимно.

Мой firewall и access_control конфигурация выглядит следующим образом: пути управления

security: 
    encoders: 
     # encoder config here 
    providers: 
     # provider config here 
firewalls: 
    dev: 
     pattern: ^/(_(profiler|wdt)|css|images|js)/ 
     security: false 
    secured: 
     anonymous: ~ 
     http_basic: ~ 

access_control: 
    - { path: ^/$, roles: ROLE_USER } 
    - { path: ^/api/, roles: ROLE_USER } 
    - { path: ^/,  roles: IS_AUTHENTICATED_ANONYMOUSLY } 

Access являются регулярные выражения, так и ^/$^/ не то же самое. Первый будет точно соответствовать только маршруту /. Последний будет соответствовать любому маршруту, начинающемуся с /; например: /home, /products, /contact и т.д.

Действительно, последний будет соответствовать и анонимно проверить подлинность /api, но это не будет соответствовать /api/ или /api/1 и т.д., как они четко определены и ограничены ROLE_USER.

Итак, общая идея состоит в том, чтобы явно и (если возможно) точно соответствовать маршрутам, которые вы хотите ограничить, и сначала объявите их. Последнее объявление ^/ должно открыто поймать любой другой маршрут, который проваливается.

+0

Я уже протестировал аннотацию @ @ Security - не работает, он все же перенаправляется на страницу входа в систему (точка входа в брандмауэр). Извините, что не упоминал об этом в описании! Я тестировал как '@Security (" has_role ('IS_AUTHENTICATED_ANONYMOUSLY') ")' и '@Security (" is_granted ('IS_AUTHENTICATED_ANONYMOUSLY') ")' – Wirone

+0

Привет @Wirone. Можете ли вы опубликовать определение 'access_control', поскольку оно может дать некоторый намек? –

+0

Я отредактировал свой вопрос, возможно, вы его не заметили :-) – Wirone

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