@@ -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