@@ -864,6 +864,8 @@ options:
|
864 | 864 | (internally, an :class:`Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException`
|
865 | 865 | is thrown);
|
866 | 866 |
|
| 867 | +* ``allow_if`` If the expression returns false, then access is denied; |
| 868 | + |
867 | 869 | * ``requires_channel`` If the incoming request's channel (e.g. ``http``)
|
868 | 870 | does not match this value (e.g. ``https``), the user will be redirected
|
869 | 871 | (e.g. redirected from ``http`` to ``https``, or vice versa).
|
@@ -951,6 +953,56 @@ address):
|
951 | 953 |
|
952 | 954 | * The second access rule is not examined as the first rule matched.
|
953 | 955 |
|
| 956 | +Securing by an Expression |
| 957 | +~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 958 | + |
| 959 | +.. versionadded:: 2.4 |
| 960 | +The ``allow_if`` functionality was introduced in Symfony 2.4. |
| 961 | + |
| 962 | +Once an ``access_control`` entry is matched, you can deny access via the |
| 963 | +``roles`` key or use more complex logic with an expression in the ``allow_if`` |
| 964 | +key: |
| 965 | + |
| 966 | +.. configuration-block:: |
| 967 | + |
| 968 | +.. code-block:: yaml |
| 969 | +
|
| 970 | +# app/config/security.yml |
| 971 | +security: |
| 972 | +# ... |
| 973 | +access_control: |
| 974 | +- |
| 975 | +path: ^/_internal/secure |
| 976 | +allow_if: "'127.0.0.1' == request.getClientIp() or has_role('ROLE_ADMIN')" |
| 977 | +
|
| 978 | + .. code-block:: xml |
| 979 | +
|
| 980 | +<access-control> |
| 981 | +<rule path="^/_internal/secure" |
| 982 | +allow-if="'127.0.0.1' == request.getClientIp() or has_role('ROLE_ADMIN')" /> |
| 983 | +</access-control> |
| 984 | +
|
| 985 | + .. code-block:: php |
| 986 | +
|
| 987 | +'access_control' => array( |
| 988 | +array( |
| 989 | +'path' => '^/_internal/secure', |
| 990 | +'allow_if' => '"127.0.0.1" == request.getClientIp() or has_role("ROLE_ADMIN")', |
| 991 | +), |
| 992 | +), |
| 993 | +
|
| 994 | +In this case, when the user tries to access any URL starting with ``/_internal/secure``, |
| 995 | +she will only be granted access if the IP address is ``127.0.0.1`` or if |
| 996 | +the user has the ``ROLE_ADMIN`` role. |
| 997 | + |
| 998 | +Inside the expression, you have access to a number of different variables |
| 999 | +and functions including ``request``, which is the Symfony |
| 1000 | +:class:`Symfony\\Component\\HttpFoundation\\Request` object (see |
| 1001 | +:ref:`component-http-foundation-request`). |
| 1002 | + |
| 1003 | +For a list of the other functions and variables, see |
| 1004 | +:ref:`functions and variables <book-security-expression-variables>`. |
| 1005 | + |
954 | 1006 | .. _book-security-securing-channel:
|
955 | 1007 |
|
956 | 1008 | Securing by Channel
|
@@ -1656,6 +1708,8 @@ doesn't need to be defined anywhere - you can just start using it.
|
1656 | 1708 | Symfony2. If you define your own roles with a dedicated ``Role`` class
|
1657 | 1709 | (more advanced), don't use the ``ROLE_`` prefix.
|
1658 | 1710 |
|
| 1711 | +.. _book-security-role-hierarchy: |
| 1712 | + |
1659 | 1713 | Hierarchical Roles
|
1660 | 1714 | ~~~~~~~~~~~~~~~~~~
|
1661 | 1715 |
|
@@ -1834,6 +1888,31 @@ the built-in helper function:
|
1834 | 1888 | idea to have a main firewall that covers all URLs (as has been shown
|
1835 | 1889 | in this chapter).
|
1836 | 1890 |
|
| 1891 | +.. _book-security-template-expression: |
| 1892 | + |
| 1893 | +.. versionadded:: 2.4 |
| 1894 | +The ``expression`` functionality was introduced in Symfony 2.4. |
| 1895 | + |
| 1896 | +You can also use expressions inside your templates: |
| 1897 | + |
| 1898 | +.. configuration-block:: |
| 1899 | + |
| 1900 | +.. code-block:: html+jinja |
| 1901 | + |
| 1902 | +{% if is_granted(expression('has_role("ROLE_ADMIN")')) %} |
| 1903 | +<a href="...">Delete</a> |
| 1904 | +{% endif %} |
| 1905 | + |
| 1906 | +.. code-block:: html+php |
| 1907 | + |
| 1908 | +<?php if ($view['security']->isGranted(new Expression( |
| 1909 | +'has_role("ROLE_ADMIN")' |
| 1910 | +))): ?> |
| 1911 | +<a href="...">Delete</a> |
| 1912 | +<?php endif; ?> |
| 1913 | + |
| 1914 | +For more details on expressions and security, see :ref:`book-security-expressions`. |
| 1915 | + |
1837 | 1916 | Access Control in Controllers
|
1838 | 1917 | -----------------------------
|
1839 | 1918 |
|
@@ -1856,6 +1935,91 @@ method of the security context::
|
1856 | 1935 | A firewall must be active or an exception will be thrown when the ``isGranted``
|
1857 | 1936 | method is called. See the note above about templates for more details.
|
1858 | 1937 |
|
| 1938 | +.. _book-security-expressions: |
| 1939 | + |
| 1940 | +Complex Access Controls with Expressions |
| 1941 | +---------------------------------------- |
| 1942 | + |
| 1943 | +.. versionadded:: 2.4 |
| 1944 | +The expression functionality was introduced in Symfony 2.4. |
| 1945 | + |
| 1946 | +In addition to a role like ``ROLE_ADMIN``, the ``isGranted`` method also |
| 1947 | +accepts an :class:`Symfony\\Component\\ExpressionLanguage\\Expression` object:: |
| 1948 | + |
| 1949 | +use Symfony\Component\Security\Core\Exception\AccessDeniedException; |
| 1950 | +use Symfony\Component\ExpressionLanguage\Expression; |
| 1951 | +// ... |
| 1952 | + |
| 1953 | +public function indexAction() |
| 1954 | +{ |
| 1955 | +if (!$this->get('security.context')->isGranted(new Expression( |
| 1956 | +'"ROLE_ADMIN" in roles or (user and user.isSuperAdmin())' |
| 1957 | +))) { |
| 1958 | +throw new AccessDeniedException(); |
| 1959 | +} |
| 1960 | + |
| 1961 | +// ... |
| 1962 | +} |
| 1963 | + |
| 1964 | +In this example, if the current user has ``ROLE_ADMIN`` or if the current |
| 1965 | +user object's ``isSuperAdmin`` method returns ``true``, then access will |
| 1966 | +be granted (note: your User object may not have an ``isSuperAdmin`` method, |
| 1967 | +that method is invented for this example). This uses an expression and you |
| 1968 | +can learn more about the expression language syntax, see :doc:`/components/expression_language/syntax`. |
| 1969 | + |
| 1970 | +.. _book-security-expression-variables: |
| 1971 | + |
| 1972 | +Inside the expression, you have access to a number of variables: |
| 1973 | + |
| 1974 | +* ``user`` The user object (or the string ``anon`` if you're not authenticated); |
| 1975 | +* ``roles`` The array of roles the user has, including from the |
| 1976 | +:ref:`role hierarchy <book-security-role-hierarchy>` but not including |
| 1977 | +the ``IS_AUTHENTICATED_*`` attributes (see the functions below); |
| 1978 | +* ``object``: The object (if any) that's passed as the second argument to |
| 1979 | +``isGranted`` ; |
| 1980 | +* ``token`` The token object; |
| 1981 | +* ``trust_resolver``: The :class:`Symfony\\Component\\Security\\Core\\Authentication\\AuthenticationTrustResolverInterface`, |
| 1982 | +object: probably not useful directly. |
| 1983 | + |
| 1984 | +Additionally, you have access to a number of functions inside the expression. |
| 1985 | +**Note**: some of these functions *look* similar to the ``IS_AUTHENTICATED_*`` |
| 1986 | +attributes, but work differently. See the note below: |
| 1987 | + |
| 1988 | +* ``is_authenticated``: Returns true if the user is authenticated via "remember-me" |
| 1989 | +or authenticated "fully" - i.e. returns true if the user is "logged in"; |
| 1990 | +* ``is_anonymous``: Equal to using ``IS_AUTHENTICATED_ANONYMOUSLY`` with |
| 1991 | +the ``isGranted`` function; |
| 1992 | +* ``is_remember_me``: Similar, but not equal to ``IS_AUTHENTICATED_REMEMBERED``, |
| 1993 | +see below; |
| 1994 | +* ``is_fully_authenticated``: Similar, but not equal to ``IS_AUTHENTICATED_FULLY``, |
| 1995 | +see below; |
| 1996 | +* ``has_role``: Checks to see if the user has the given role - equivalent |
| 1997 | +to an expression like ``'ROLE_ADMIN' in roles``. |
| 1998 | + |
| 1999 | +.. sidebar:: ``is_remember_me`` is different than checking ``IS_AUTHENTICATED_REMEMBERED`` |
| 2000 | + |
| 2001 | +The ``is_remember_me`` and ``is_authenticated_fully`` functions are *similar* |
| 2002 | +to using ``IS_AUTHENTICATED_REMEMBERED`` and ``IS_AUTHENTICATED_FULLY`` |
| 2003 | +with the ``isGranted`` function - but they are **not** the same. The |
| 2004 | +following shows the difference:: |
| 2005 | + |
| 2006 | +use Symfony\Component\ExpressionLanguage\Expression; |
| 2007 | +// ... |
| 2008 | + |
| 2009 | +$sc = $this->get('security.context'); |
| 2010 | +$access1 = $sc->isGranted('IS_AUTHENTICATED_REMEMBERED'); |
| 2011 | + |
| 2012 | +$access2 = $sc->isGranted(new Expression( |
| 2013 | +'is_remember_me() or is_fully_authenticated()' |
| 2014 | +)); |
| 2015 | + |
| 2016 | +Here, ``$access1`` and ``$access2`` will be the same value. Unlike the |
| 2017 | +behavior of ``IS_AUTHENTICATED_REMEMBERED`` and ``IS_AUTHENTICATED_FULLY``, |
| 2018 | +the ``is_remember_me`` function *only* returns true if the user is authenticated |
| 2019 | +via a remember me cookie and ``is_fully_authenticated`` *only* returns |
| 2020 | +true if the user has actually logged in during this session (i.e. is |
| 2021 | +full-fledged). |
| 2022 | + |
1859 | 2023 | Impersonating a User
|
1860 | 2024 | --------------------
|
1861 | 2025 |
|
|
0 commit comments