|
16 | 16 |
|
17 | 17 | * :ref:`Configuring services <book-services-expressions>`;
|
18 | 18 | * :ref:`Route matching conditions <book-routing-conditions>`;
|
19 |
| -* :ref:`Checking security <book-security-expressions>` and |
| 19 | +* :ref:`Checking security <book-security-expressions>` (explained below) and |
20 | 20 | :ref:`access controls with allow_if <book-security-allow-if>`;
|
21 | 21 | * :doc:`Validation </reference/constraints/Expression>`.
|
22 | 22 |
|
23 | 23 | For more information about how to create and work with expressions, see
|
24 | 24 | :doc:`/components/expression_language/syntax`.
|
| 25 | + |
| 26 | +.. _book-security-expressions: |
| 27 | + |
| 28 | +Security: Complex Access Controls with Expressions |
| 29 | +-------------------------------------------------- |
| 30 | + |
| 31 | +.. versionadded:: 2.4 |
| 32 | + The expression functionality was introduced in Symfony 2.4. |
| 33 | + |
| 34 | +In addition to a role like ``ROLE_ADMIN``, the ``isGranted`` method also |
| 35 | +accepts an :class:`Symfony\\Component\\ExpressionLanguage\\Expression` object:: |
| 36 | + |
| 37 | + use Symfony\Component\ExpressionLanguage\Expression; |
| 38 | + // ... |
| 39 | + |
| 40 | + public function indexAction() |
| 41 | + { |
| 42 | + if (!$this->get('security.context')->isGranted(new Expression( |
| 43 | + '"ROLE_ADMIN" in roles or (user and user.isSuperAdmin())' |
| 44 | + ))) { |
| 45 | + throw $this->createAccessDeniedException(); |
| 46 | + } |
| 47 | + |
| 48 | + // ... |
| 49 | + } |
| 50 | + |
| 51 | +In this example, if the current user has ``ROLE_ADMIN`` or if the current |
| 52 | +user object's ``isSuperAdmin()`` method returns ``true``, then access will |
| 53 | +be granted (note: your User object may not have an ``isSuperAdmin`` method, |
| 54 | +that method is invented for this example). |
| 55 | + |
| 56 | +This uses an expression and you can learn more about the expression language |
| 57 | +syntax, see :doc:`/components/expression_language/syntax`. |
| 58 | + |
| 59 | +.. _book-security-expression-variables: |
| 60 | + |
| 61 | +Inside the expression, you have access to a number of variables: |
| 62 | + |
| 63 | +``user`` |
| 64 | + The user object (or the string ``anon`` if you're not authenticated). |
| 65 | +``roles`` |
| 66 | + The array of roles the user has, including from the |
| 67 | + :ref:`role hierarchy <book-security-role-hierarchy>` but not including the |
| 68 | + ``IS_AUTHENTICATED_*`` attributes (see the functions below). |
| 69 | +``object`` |
| 70 | + The object (if any) that's passed as the second argument to ``isGranted``. |
| 71 | +``token`` |
| 72 | + The token object. |
| 73 | +``trust_resolver`` |
| 74 | + The :class:`Symfony\\Component\\Security\\Core\\Authentication\\AuthenticationTrustResolverInterface`, |
| 75 | + object: you'll probably use the ``is_*`` functions below instead. |
| 76 | + |
| 77 | +Additionally, you have access to a number of functions inside the expression: |
| 78 | + |
| 79 | +``is_authenticated`` |
| 80 | + Returns ``true`` if the user is authenticated via "remember-me" or authenticated |
| 81 | + "fully" - i.e. returns true if the user is "logged in". |
| 82 | +``is_anonymous`` |
| 83 | + Equal to using ``IS_AUTHENTICATED_ANONYMOUSLY`` with the ``isGranted`` function. |
| 84 | +``is_remember_me`` |
| 85 | + Similar, but not equal to ``IS_AUTHENTICATED_REMEMBERED``, see below. |
| 86 | +``is_fully_authenticated`` |
| 87 | + Similar, but not equal to ``IS_AUTHENTICATED_FULLY``, see below. |
| 88 | +``has_role`` |
| 89 | + Checks to see if the user has the given role - equivalent to an expression like |
| 90 | + ``'ROLE_ADMIN' in roles``. |
| 91 | + |
| 92 | +.. sidebar:: ``is_remember_me`` is different than checking ``IS_AUTHENTICATED_REMEMBERED`` |
| 93 | + |
| 94 | + The ``is_remember_me`` and ``is_authenticated_fully`` functions are *similar* |
| 95 | + to using ``IS_AUTHENTICATED_REMEMBERED`` and ``IS_AUTHENTICATED_FULLY`` |
| 96 | + with the ``isGranted`` function - but they are **not** the same. The |
| 97 | + following shows the difference:: |
| 98 | + |
| 99 | + use Symfony\Component\ExpressionLanguage\Expression; |
| 100 | + // ... |
| 101 | + |
| 102 | + $sc = $this->get('security.context'); |
| 103 | + $access1 = $sc->isGranted('IS_AUTHENTICATED_REMEMBERED'); |
| 104 | + |
| 105 | + $access2 = $sc->isGranted(new Expression( |
| 106 | + 'is_remember_me() or is_fully_authenticated()' |
| 107 | + )); |
| 108 | + |
| 109 | + Here, ``$access1`` and ``$access2`` will be the same value. Unlike the |
| 110 | + behavior of ``IS_AUTHENTICATED_REMEMBERED`` and ``IS_AUTHENTICATED_FULLY``, |
| 111 | + the ``is_remember_me`` function *only* returns true if the user is authenticated |
| 112 | + via a remember-me cookie and ``is_fully_authenticated`` *only* returns |
| 113 | + true if the user has actually logged in during this session (i.e. is |
| 114 | + full-fledged). |
0 commit comments