Skip to content

Commit cb6f846

Browse files
committed
Merge branch '2.7'
* 2.7: [#4606] Getting my XML (and PHP) on in the new security chapter [#4606] Tweaks thanks entirely to stof Changing to _ for consistency [#4606] Updating thanks to comments from everyone! Completely re-reading the security book Misc changes [Cookbook] Fix XML example of RTE
2 parents 8131844 + 02d594c commit cb6f846

24 files changed

+1831
-1725
lines changed

best_practices/controllers.rst

+7-3
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ for the homepage of our app:
110110
*/
111111
public function indexAction()
112112
{
113-
$em = $this->getDoctrine()->getManager();
114-
$posts = $em->getRepository('App:Post')->findLatest();
113+
$posts = $this->getDoctrine()
114+
->getRepository('AppBundle:Post')
115+
->findLatest();
115116
116117
return $this->render('default/index.html.twig', array(
117118
'posts' => $posts
@@ -136,6 +137,7 @@ For example:
136137

137138
.. code-block:: php
138139
140+
use AppBundle\Entity\Post;
139141
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
140142
141143
/**
@@ -146,7 +148,7 @@ For example:
146148
$deleteForm = $this->createDeleteForm($post);
147149
148150
return $this->render('admin/post/show.html.twig', array(
149-
'post' => $post,
151+
'post' => $post,
150152
'delete_form' => $deleteForm->createView(),
151153
));
152154
}
@@ -188,8 +190,10 @@ flexible:
188190

189191
.. code-block:: php
190192
193+
use AppBundle\Entity\Post;
191194
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
192195
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
196+
use Symfony\Component\HttpFoundation\Request;
193197
194198
/**
195199
* @Route("/comment/{postSlug}/new", name = "comment_new")

book/security.rst

+691-1,716
Large diffs are not rendered by default.

components/map.rst.inc

+1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
* :doc:`/components/security/firewall`
127127
* :doc:`/components/security/authentication`
128128
* :doc:`/components/security/authorization`
129+
* :doc:`/components/security/secure_tools`
129130

130131
* **Serializer**
131132

components/security/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ Security
88
firewall
99
authentication
1010
authorization
11+
secure_tools

components/security/secure_tools.rst

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
Securely Comparing Strings and Generating Random Numbers
2+
========================================================
3+
4+
The Symfony Security component comes with a collection of nice utilities
5+
related to security. These utilities are used by Symfony, but you should
6+
also use them if you want to solve the problem they address.
7+
8+
Comparing Strings
9+
~~~~~~~~~~~~~~~~~
10+
11+
The time it takes to compare two strings depends on their differences. This
12+
can be used by an attacker when the two strings represent a password for
13+
instance; it is known as a `Timing attack`_.
14+
15+
Internally, when comparing two passwords, Symfony uses a constant-time
16+
algorithm; you can use the same strategy in your own code thanks to the
17+
:class:`Symfony\\Component\\Security\\Core\\Util\\StringUtils` class::
18+
19+
use Symfony\Component\Security\Core\Util\StringUtils;
20+
21+
// is some known string (e.g. password) equal to some user input?
22+
$bool = StringUtils::equals($knownString, $userInput);
23+
24+
.. caution::
25+
26+
To avoid timing attacks, the known string must be the first argument
27+
and the user-entered string the second.
28+
29+
Generating a Secure random Number
30+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31+
32+
Whenever you need to generate a secure random number, you are highly
33+
encouraged to use the Symfony
34+
:class:`Symfony\\Component\\Security\\Core\\Util\\SecureRandom` class::
35+
36+
use Symfony\Component\Security\Core\Util\SecureRandom;
37+
38+
$generator = new SecureRandom();
39+
$random = $generator->nextBytes(10);
40+
41+
The
42+
:method:`Symfony\\Component\\Security\\Core\\Util\\SecureRandom::nextBytes`
43+
method returns a random string composed of the number of characters passed as
44+
an argument (10 in the above example).
45+
46+
The SecureRandom class works better when OpenSSL is installed. But when it's
47+
not available, it falls back to an internal algorithm, which needs a seed file
48+
to work correctly. Just pass a file name to enable it::
49+
50+
use Symfony\Component\Security\Core\Util\SecureRandom;
51+
52+
$generator = new SecureRandom('/some/path/to/store/the/seed.txt');
53+
$random = $generator->nextBytes(10);
54+
55+
.. note::
56+
57+
If you're using the Symfony Framework, you can access a secure random
58+
instance directly from the container: its name is ``security.secure_random``.
59+
60+
.. _`Timing attack`: http://en.wikipedia.org/wiki/Timing_attack

cookbook/doctrine/resolve_target_entity.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ about the replacement:
132132
<doctrine:config>
133133
<doctrine:orm>
134134
<!-- ... -->
135-
<doctrine:resolve-target-entity interface="Acme\InvoiceBundle\Model\InvoiceSubjectInterface">Acme\AppBundle\Entity\Customer</resolve-target-entity>
135+
<doctrine:resolve-target-entity interface="Acme\InvoiceBundle\Model\InvoiceSubjectInterface">Acme\AppBundle\Entity\Customer</doctrine:resolve-target-entity>
136136
</doctrine:orm>
137137
</doctrine:config>
138138
</container>

cookbook/expression/expressions.rst

+91-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,99 @@ ways:
1616

1717
* :ref:`Configuring services <book-services-expressions>`;
1818
* :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
2020
:ref:`access controls with allow_if <book-security-allow-if>`;
2121
* :doc:`Validation </reference/constraints/Expression>`.
2222

2323
For more information about how to create and work with expressions, see
2424
: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).

cookbook/map.rst.inc

+3
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144

145145
* :doc:`/cookbook/security/index`
146146

147+
* :doc:`/cookbook/security/form_login_setup`
147148
* :doc:`/cookbook/security/entity_provider`
148149
* :doc:`/cookbook/security/remember_me`
149150
* :doc:`/cookbook/security/impersonating_user`
@@ -164,6 +165,8 @@
164165
* :doc:`/cookbook/security/target_path`
165166
* :doc:`/cookbook/security/csrf_in_login_form`
166167
* :doc:`/cookbook/security/named_encoders`
168+
* :doc:`/cookbook/security/access_control`
169+
* :doc:`/cookbook/security/multiple_user_providers`
167170

168171
* **Serializer**
169172

0 commit comments

Comments
 (0)