From 2a85e4f20f78e19f1b947a75e8bafd52bb4f22ff Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Thu, 16 Jul 2015 10:43:11 +0200 Subject: [PATCH 1/2] Added user_checkers.rst --- cookbook/security/index.rst | 1 + cookbook/security/user_checkers.rst | 218 ++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 cookbook/security/user_checkers.rst diff --git a/cookbook/security/index.rst b/cookbook/security/index.rst index c9a478c927a..3efdd455016 100644 --- a/cookbook/security/index.rst +++ b/cookbook/security/index.rst @@ -23,6 +23,7 @@ Authentication (Identifying/Logging in the User) multiple_user_providers firewall_restriction host_restriction + user_checkers Authorization (Denying Access) ------------------------------ diff --git a/cookbook/security/user_checkers.rst b/cookbook/security/user_checkers.rst new file mode 100644 index 00000000000..28186db702f --- /dev/null +++ b/cookbook/security/user_checkers.rst @@ -0,0 +1,218 @@ +.. index:: + single: Security; Creating and Enabling Custom User Checkers + +How to Create and Enable Custom User Checkers +============================================= + +During the authentication of a user, additional checks might be required to verify +if the identified user is allowed to log in. By defining custom user checkers, you +can define per firewall which checkers should be used. + +.. versionadded:: 2.8 +Adding custom user checkers was introduced in Symfony 2.8. + + +Creating a Custom User Checker +------------------------------ + +User checkers are defined in PHP classes that must implement the +:class:`UserCheckerInterface Symfony\\Component\\Security\\Core\\UserCheckerInterface`. +This interface defines two methods called ``checkPreAuth()`` and ``checkPostAuth()`` +to perform checks before and after user authentication. If one or more +conditions are not met, an exception should be thrown which extends the +:class:`AccountStatusException Symfony\\Component\\Security\\Core\\Exception\\AccountStatusException` + +.. code-block:: php + + namespace App\Security; + + use Symfony\Component\Security\Core\User\UserCheckInterface; + + class UserChecker implements UserCheckerInterface + { + public function checkPreAuth(UserInterface $user) + { + if (!$user instanceof AppUser) { + return; + } + + // user is deleted, show a generic Account Not Found message. + if ($user->isDeleted()) { + throw new AccountDeletedException('...'); + } + } + + public function checkPostAuth(UserInterface $user) + { + if (!$user instanceof AppUser) { + return; + } + + // user account is expired, the user may be notified + if ($user->isExpired()) { + throw new AccountExpiredException('...'); + } + } + } + +Enabling the Custom User Checker +-------------------------------- + +All that's left to be done is creating a service definition and configuring +this in the firewall configuration. Configuring the service is done like any +other service: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/services.yml + services: + app.user_checker: + class: App\Security\UserChecker + + .. code-block:: xml + + + + + + + + + + + + .. code-block:: php + + // app/config/services.php + use Symfony\Component\DependencyInjection\Definition; + + $userChecker = new Definition('App\Security\UserChecker'); + $container->setDefinition('app.user_checker', $userChecker); + +All that's left to do is add the checker to the desired firewall where the value +is the service id of your user checker: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + + # ... + security: + firewalls: + secured_area: + pattern: ^/ + user_checkers: ["app.user_checker"] + # ... + + .. code-block:: xml + + + + + + + + + app.user_checker + + + + + + .. code-block:: php + + // app/config/security.php + + // ... + $container->loadFromExtension('security', array( + 'firewalls' => array( + 'secured_area' => array( + 'pattern' => '^/', + 'user_checkers' => array('app.user_checker'), + // ... + ), + ), + )); + + +Additional Configurations +------------------------- + +It's possible to add multiple user checkers to one firewall while +configuring only one user checker for another firewall. When adding +multiple user checkers, they are executed in the same sequence as +defined in your configuration. + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + + # ... + security: + firewalls: + admin: + pattern: ^/admin + user_checkers: ["app.user_checker", "app.admin_checker"] + # ... + secured_area: + pattern: ^/ + user_checkers: ["app.user_checker"] + + .. code-block:: xml + + + + + + + + + app.user_checker + app.admin_checker + + + + app.user_checker + + + + + + .. code-block:: php + + // app/config/security.php + + // ... + $container->loadFromExtension('security', array( + 'firewalls' => array( + 'admin' => array( + 'pattern' => '^/admin', + 'user_checkers' => array( + 'app.user_checker', + 'app.admin_checker', + ), + // ... + ), + 'secured_area' => array( + 'pattern' => '^/', + 'user_checkers' => array('app.user_checker'), + // ... + ), + ), + )); From d070f5be71dfb75d8be113d7d69a47a119a0f498 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Thu, 1 Oct 2015 07:19:58 +0200 Subject: [PATCH 2/2] Updated according to the feature modifications Instead of multiple User Checkers, only 1 is configured --- cookbook/security/user_checkers.rst | 41 +++++++++++++---------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/cookbook/security/user_checkers.rst b/cookbook/security/user_checkers.rst index 28186db702f..83ef18e63c3 100644 --- a/cookbook/security/user_checkers.rst +++ b/cookbook/security/user_checkers.rst @@ -5,11 +5,11 @@ How to Create and Enable Custom User Checkers ============================================= During the authentication of a user, additional checks might be required to verify -if the identified user is allowed to log in. By defining custom user checkers, you -can define per firewall which checkers should be used. +if the identified user is allowed to log in. By defining a custom user checker, you +can define per firewall which checker should be used. .. versionadded:: 2.8 -Adding custom user checkers was introduced in Symfony 2.8. + Defining a custom user checker was introduced in Symfony 2.8. Creating a Custom User Checker @@ -80,8 +80,7 @@ other service: xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - + @@ -107,7 +106,7 @@ is the service id of your user checker: firewalls: secured_area: pattern: ^/ - user_checkers: ["app.user_checker"] + user_checker: app.user_checker # ... .. code-block:: xml @@ -123,7 +122,7 @@ is the service id of your user checker: - app.user_checker + app.user_checker @@ -138,7 +137,7 @@ is the service id of your user checker: 'firewalls' => array( 'secured_area' => array( 'pattern' => '^/', - 'user_checkers' => array('app.user_checker'), + 'user_checker' => 'app.user_checker', // ... ), ), @@ -148,10 +147,7 @@ is the service id of your user checker: Additional Configurations ------------------------- -It's possible to add multiple user checkers to one firewall while -configuring only one user checker for another firewall. When adding -multiple user checkers, they are executed in the same sequence as -defined in your configuration. +It's possible to have a different user checker per firewall. .. configuration-block:: @@ -164,11 +160,11 @@ defined in your configuration. firewalls: admin: pattern: ^/admin - user_checkers: ["app.user_checker", "app.admin_checker"] + user_checker: app.admin_user_checker # ... secured_area: pattern: ^/ - user_checkers: ["app.user_checker"] + user_checker: app.user_checker .. code-block:: xml @@ -183,12 +179,11 @@ defined in your configuration. - app.user_checker - app.admin_checker + app.admin_user_checker - app.user_checker + app.user_checker @@ -203,16 +198,18 @@ defined in your configuration. 'firewalls' => array( 'admin' => array( 'pattern' => '^/admin', - 'user_checkers' => array( - 'app.user_checker', - 'app.admin_checker', - ), + 'user_checkers' => 'app.admin_user_checker' // ... ), 'secured_area' => array( 'pattern' => '^/', - 'user_checkers' => array('app.user_checker'), + 'user_checker' => 'app.user_checker', // ... ), ), )); + +.. note:: + + Internally the user checkers are aliased per firewall. For `secured_area` the alias + `security.user_checker.secured_area` would point to `app.user_checker`.