diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc index d57650320c7..7f96d19c747 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -176,6 +176,7 @@ * :doc:`/cookbook/security/csrf_in_login_form` * :doc:`/cookbook/security/named_encoders` * :doc:`/cookbook/security/multiple_user_providers` + * :doc:`/cookbook/security/multiple_guard_authenticators` * :doc:`/cookbook/security/firewall_restriction` * :doc:`/cookbook/security/host_restriction` * :doc:`/cookbook/security/user_checkers` diff --git a/cookbook/security/index.rst b/cookbook/security/index.rst index ed13a2116f9..61efff1aa23 100644 --- a/cookbook/security/index.rst +++ b/cookbook/security/index.rst @@ -22,6 +22,7 @@ Authentication (Identifying/Logging in the User) csrf_in_login_form named_encoders multiple_user_providers + multiple_guard_authenticators firewall_restriction host_restriction user_checkers diff --git a/cookbook/security/multiple_guard_authenticators.rst b/cookbook/security/multiple_guard_authenticators.rst new file mode 100644 index 00000000000..acb1f774422 --- /dev/null +++ b/cookbook/security/multiple_guard_authenticators.rst @@ -0,0 +1,172 @@ +How to Use Multiple Guard Authenticators +======================================== + +.. versionadded:: 2.8 + The ``Guard`` component was introduced in Symfony 2.8. + +The Guard authentication component allows you to easily use many different +authenticators at a time. + +An entry point is a service id (of one of your authenticators) whose +``start()`` method is called to start the authentication process. + +Multiple Authenticators with Shared Entry Point +----------------------------------------------- + +Sometimes you want to offer your users different authentication mechanisms like +a form login and a Facebook login while both entry points redirect the user to +the same login page. +However, in your configuration you have to explicitly say which entry point +you want to use. + +This is how your security configuration can look in action: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + security: + # ... + firewalls: + default: + anonymous: ~ + guard: + authenticators: + - app.form_login_authenticator + - app.facebook_connect_authenticator + entry_point: app.form_login_authenticator + + .. code-block:: xml + + + + + + + + + + + app.form_login_authenticator + app.facebook_connect_authenticator + + + + + + .. code-block:: php + + // app/config/security.php + $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( + 'default' => array( + 'anonymous' => null, + 'guard' => array( + 'entry_point' => 'app.form_login_authenticator', + 'authenticators' => array( + 'app.form_login_authenticator', + 'app.facebook_connect_authenticator' + ), + ), + ), + ), + )); + +There is one limitation with this approach - you have to use exactly one entry point. + +Multiple Authenticators with Separate Entry Points +-------------------------------------------------- + +However, there are use cases where you have authenticators that protect different +parts of your application. For example, you have a login form that protects +the secured area of your application front-end and API end points that are +protected with API tokens. As you can only configure one entry point per firewall, +the solution is to split the configuration into two separate firewalls: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + security: + # ... + firewalls: + api: + pattern: ^/api/ + guard: + authenticators: + - app.api_token_authenticator + default: + anonymous: ~ + guard: + authenticators: + - app.form_login_authenticator + access_control: + - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } + - { path: ^/api, roles: ROLE_API_USER } + - { path: ^/, roles: ROLE_USER } + + .. code-block:: xml + + + + + + + + + + app.api_token_authenticator + + + + + + app.form_login_authenticator + + + + + + + + + .. code-block:: php + + // app/config/security.php + $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( + 'api' => array( + 'pattern' => '^/api', + 'guard' => array( + 'authenticators' => array( + 'app.api_token_authenticator', + ), + ), + ), + 'default' => array( + 'anonymous' => null, + 'guard' => array( + 'authenticators' => array( + 'app.form_login_authenticator', + ), + ), + ), + ), + 'access_control' => array( + array('path' => '^/login', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'), + array('path' => '^/api', 'role' => 'ROLE_API_USER'), + array('path' => '^/', 'role' => 'ROLE_USER'), + ), + ));