diff --git a/components/security/core/authentication.rst b/components/security/core/authentication.rst new file mode 100644 index 00000000000..4708740965b --- /dev/null +++ b/components/security/core/authentication.rst @@ -0,0 +1,229 @@ +.. index:: + single: Security, Core Authentication + +Security Core: Authentication +============================= + +As you've :ref:`already learned `, the first +step in the Security system is authentication, answering the question: **Who +are you?** + +Authentication Manager +---------------------- + +This question is answered by an +:class:`authentication manager `. +This class recieves a token containing the information available about the +visitor of your application. Based on this information, it tries to determine +the visitor and returns an authenticated token. If it can't authenticate the +user, an +:class:`Symfony\\Component\\Security\\Core\\Exception\\AuthenticationException` +is thrown. This exception can the be transformed into a redirect to the login +form, for example. + +Using the authentication manager, authenticating a user becomes very simple (no +worries, you'll fill the missing variables within a couple of minutes):: + + use Symfony\Component\Security\Core\Exception\AuthenticationException; + + try { + $authenticatedToken = $authManager->authenticate($unauthenticatedToken); + } catch (AuthenticationException $e) { + // ... authentication failed, do something + } + +The Security component comes with one very flexible authentication manager, the +:class:`Symfony\\Component\\Security\\Core\\Authentication\\AuthenticationProviderManager`. +This uses authentication providers to authenticate a token. + +.. _component-security-core-authentication-providers: + +Authentication Providers +~~~~~~~~~~~~~~~~~~~~~~~~ + +One ``AuthenticationProviderManager`` can have multiple +:class:`authentication providers `. +Using the ``supports()`` method, providers determines if they can authenticate +the passed token. + +The most simple authentication provider is the +``AnonymousAuthenticationProvider``. This providers "authenticates" an +``AnonymousToken``. Anonymous users are guests, they aren't registered for the +application, but they are still authenticated. + +.. code-block:: php + + // ... + use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager; + use Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider; + use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; + + $anonToken = new AnonymousToken('a_custom_key', 'Guest'.uniqid()); + + // 'a_custom_key' has to match the 1st argument of AnonymousToken. + $anonymousAuthProvider = new AnonymousAuthenticationProvider('a_custom_key'); + + $authManager = new AuthenticationProviderManager(array( + $anonymousAuthProvider, + )); + + try { + $authenticatedToken = $authManager->authenticate($unauthenticatedToken); + } catch (AuthenticationException $e) { + // ... authentication failed, do something + } + + // user is authenticated as a guest + +In this example, each requests to the application will result in an +authenticated anonymous token with different names starting with ``Guest``. + +The DaoAuthenticationProvider (Data Access Object) +.................................................. + +This authentication provider is one of the most common authentication +providers. It'll authenticate an ``UsernamePasswordToken``, retrieve the user, +check the password and then return an authenticated ``UsernamePasswordToken`` +containing the user object. That's quite a lot, the following paragraphs each +explain one of these steps. + +The first step is to retrieve the user. The dao provider does this with the +help of a +:class:`user provider `. +This can provide users from a database for example. The most basic user +provider is the ``InMemoryUserProvider``, which provides users from an array:: + + use Symfony\Component\Security\Core\User\InMemoryUserProvider; + + $userProvider = new InMemoryUserProvider(array( + 'wouter' => array('password' => 'pa$$'), + )); + +After the user is retrieved, the dao provider checks if the password from the +token and the user provided by the user provider (based on its username) are +the same. It does this with the help of a +:class:`password encoder `. +This encodes the password in the token in the same way as the password was +encoded during registration and then compares the two. As the password was +saved in plain text (for demostration purposes), you're going to need the +``PlaintextPasswordEncoder``. + +In order to be able to authenticate different types of users, using different +encoding strategies, you'll pass an ``EncoderFactory`` instance. This factory +is configured with the correct encoder for the correct user type. + +.. code-block:: php + + use Symfony\Component\Security\Core\Encoder\EncoderFactory; + use Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder; + + $encoderFactory = new EncoderFactory(array( + // this is the FQCN to the user object used by the in memory user provider + 'Symfony\Component\Security\Core\User\User' => new PlaintextPasswordEncoder(), + )); + +Now the user is retrieved and matched against the submitted password, the dao +provider has to do some final checks. For instance, if the user is not banned +or if the account is not expired. Such checks are done by +:class:`user checkers `:: + + use Symfony\Component\Security\Core\User\UserChecker; + + $userChecker = new UserChecker(); + +Everything is now set-up and ready to be combined into the dao authentication +provider! + +.. code-block:: + + use Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider; + use Symfony\Component\Security\Core\Encoder\EncoderFactory; + use Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder; + use Symfony\Component\Security\Core\User\InMemoryUserProvider; + use Symfony\Component\Security\Core\User\UserChecker; + + $userProvider = new InMemoryUserProvider(array( + 'wouter' => array('password' => 'pa$$'), + )); + + $encoderFactory = new EncoderFactory(array( + // this is the FQCN to the user object used by the in memory user provider + 'Symfony\Component\Security\Core\User\User' => new PlaintextPasswordEncoder(), + )); + + $userChecker = new UserChecker(); + + $daoAuthProvider = new DaoAuthenticationProvider( + $userProvider, + $userChecker, + 'default', // used to group multiple providers + $encoderFactory + ); + +You can now inject the dao authentication provider in your authentication +manager:: + + // ... + $anonymousAuthProvider = new AnonymousAuthenticationProvider('a_custom_key'); + + $authManager = new AuthenticationProviderManager(array( + $daoAuthProvider, + $anonymousAuthProvider, + )); + +Now, you can test this out. As both the dao and anonymous authentication +providers are configured, you can now authenticate an anonymous user as well as +a real member:: + + // ... + use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; + + $token = new UsernamePasswordToken( + 'wouter', // username + 'pa$$', // password + 'default' // provider key (used to determine which providers are targetted) + ); + + try { + $authenticatedToken = $authManager->authenticate($token); + } catch (AuthenticationException $e) { + // ... bummer, user submitted a wrong username/password or has not been registered + } + + // ... user is authenticated and a real member! + +Other Authentication Providers +.............................. + +The component contains some other authentication providers: + +:class:`Symfony\\Component\\Security\\Core\\Authentication\\Provider\\RememberMeAuthenticationProvider` + This can authenticate a + :class:`Symfony\\Component\\Security\\Core\\Authentication\\Token\\RememberMeToken`, + which can be used to be automatically logged in again after the current + session expired. + +:class:`Symfony\\Component\\Security\\Core\\Authentication\\Provider\\SimpleAuthenticationProvider` + This authentication provider provides a simple way to customize the + authentication process. You use this provider to implement a custom way to + authenticate. + +:class:`Symfony\\Component\\Security\\Core\\Authentication\\Provider\\UserAuthenticationProvider` (abstract) + This is a base class for authentication providers dealing with the + ``UsernamePasswordToken`` (like the dao provider). + +Wrapping Up +----------- + +This chapter, you've implemented a very simple authentication part of the +Security system. As you've probably seen a lot of new stuff, this is a good +moment to recap what you've learned: + +#. Authentication is done by an *authentication manager* +#. The authentication manager uses *authentication provider* to transform and + *unauthenticated token* into an authenticated one. +#. The *dao authentication provider* is commonly used. It's behaviour can be + customized by implementing custom *user providers*, *user checkers* and + *password encoders*. +#. Other authentication providers are the *anonymous*, *rembember me* and + *simple* providers. diff --git a/components/security/core/index.rst b/components/security/core/index.rst new file mode 100644 index 00000000000..030e0d22572 --- /dev/null +++ b/components/security/core/index.rst @@ -0,0 +1,7 @@ +Security Core +============= + +.. toctree:: + :maxdepth: 2 + + authentication diff --git a/components/security/index.rst b/components/security/index.rst index e9fa2c24b14..8382e4cc66f 100644 --- a/components/security/index.rst +++ b/components/security/index.rst @@ -5,7 +5,5 @@ Security :maxdepth: 2 introduction - firewall - authentication - authorization - secure_tools \ No newline at end of file + core/index + secure_tools diff --git a/components/security/introduction.rst b/components/security/introduction.rst index 982834e6ab6..2dfd94a626c 100644 --- a/components/security/introduction.rst +++ b/components/security/introduction.rst @@ -4,12 +4,13 @@ The Security Component ====================== - The Security component provides a complete security system for your web - application. It ships with facilities for authenticating using HTTP basic - or digest authentication, interactive form login or X.509 certificate - login, but also allows you to implement your own authentication strategies. - Furthermore, the component provides ways to authorize authenticated users - based on their roles, and it contains an advanced ACL system. + + The Security component provides a complete security system for your + application. It's flexible enough to solve the most basic security needs + (form login or HTTP basic/digest), but also to serve as a complex security + system (X.509 certificate or custom authentication systems). Furthermore, + the component provides ways to authorize authenticated users based on their + roles or using an advanced ACL system. Installation ------------ @@ -21,12 +22,88 @@ You can install the component in 2 different ways: .. include:: /components/require_autoload.rst.inc -Sections +.. _components-security-terminology: + +Security Terminology +-------------------- + +Security is a quite complex task and has some terminology that you won't often +find in other type of programming libraries. That's why it's good to make sure +you know some of the terms used in the Security component before starting to +dive into it. + +**Authentication** + This is the first of the two phases in the Security component. During this + phase, the security tries to answer one question: **Who are you?** The + answer to this question might be retrieved from a session or from a token, + to name some examples. + +**Authorization** + This is the second phase and it tries to answer another question: **Are you + allowed to access this?** The security system knows who you are and what + you are allowed to do, now it has to decide if you fit the requirements for + the requested action. E.g. do you have admin rights, when trying to access + the admin dashboard. + +**Token** + The token is the central object in the Security system. It contains all + information that the security system has to know. For instance, if you + login, it contains the submitted username and password. After you've logged + in, it contains your rights. + +**Roles** + This is another naming for rights. It tells your "role" in the application + (e.g. user, admin or moderator, etc.). + +Usage +----- + +Now you know some terms, you already have a very global overview of the flow in +the Security component (be aware that this code is *not* working in the current +state):: + + // The authentication manager answers *Who are you?* + $authenticationManager = ...; + + // Keeps track of the token during the lifetime of the token + $tokenStorage = ...; + + // The authenticator transforms an unauthenticated token into an + // authenticated one + $authenticatedToken = $authenticationManager->authenticate(new Token(...)); + + $tokenStorage->setToken($authenticatedToken); + + // The authorization checker is the access point of the Authorization phase + $authorizationChecker = ...; + + // This code checks if admin is your role in the application + if (!$authorizationChecker->isGranted('ROLE_ADMIN')) { + throw new AccessDeniedException(); + } + + // ... show something secret, all Security checks are done! + +The Security component itself consists of a couple of sub-components, with Core +and Http being the two big ones. Besides this, it contains a sub-components for +CSRF protection and ACL (Access Control Lists) systems. + +The Security Core component contains the actual Security system, decoupled from +possible access points (e.g. web request). This means it's usable in every +application (e.g. a CLI application or a web application). + +The Security Http component is a wrapper around the Core component, providing +integration into "HTTP-land" using the +:doc:`HttpFoundation component `. + +In the next chapters, you'll learn more about these 2 sub-components. + +Chapters -------- -* :doc:`/components/security/firewall` -* :doc:`/components/security/authentication` -* :doc:`/components/security/authorization` +* :doc:`/components/security/core/authentication` +* :doc:`/components/security/core/authorization` +* :doc:`/components/security/http` * :doc:`/components/security/secure_tools` .. _Packagist: https://packagist.org/packages/symfony/security