8000 Tweaking the excellent new securing_services cookbook entry · phreaknerd/symfony-docs@a85bae3 · GitHub
[go: up one dir, main page]

Skip to content

Commit a85bae3

Browse files
committed
Tweaking the excellent new securing_services cookbook entry
Also hooking up a few missing links, which included just a little bit of new config reference (that still needs much work)
1 parent 48dfae0 commit a85bae3

File tree

4 files changed

+147
-93
lines changed

4 files changed

+147
-93
lines changed

book/security.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ The form has very few requirements. First, by submitting the form to ``/login_ch
485485
(via the ``login_check`` route), the security system will intercept the form
486486
submission and process the form for you automatically. Second, the security
487487
system expects the submitted fields to be called ``_username`` and ``_password``
488-
(these field names can be :ref:`configured</reference-security-firewall-form-username>`).
488+
(these field names can be :ref:`configured<reference-security-firewall-form-login>`).
489489

490490
And that's it! When you submit the form, the security system will automatically
491491
check the user's credentials and either authenticate the user or send the
@@ -512,6 +512,8 @@ user to a specific URL.
512512
For more details on this and how to customize the form login process in general,
513513
see :doc:`/cookbook/security/form_login`.
514514

515+
.. _book-security-common-pitfalls:
516+
515517
.. sidebar:: Avoid Common Pitfalls
516518

517519
When setting up your login form, watch out for a few common pitfalls.
@@ -714,6 +716,8 @@ Any URL like ``/admin/blog`` will match the second rule and require ``ROLE_ADMIN
714716
You can also force ``HTTP`` or ``HTTPS`` via an ``access_control`` entry.
715717
For more information, see :doc:`/cookbook/security/force_https`.
716718

719+
.. _book-security-securing-controller:
720+
717721
Securing a Controller
718722
~~~~~~~~~~~~~~~~~~~~~
719723

@@ -735,6 +739,8 @@ authorization from inside a controller:
735739
// ...
736740
}
737741
742+
.. _book-security-securing-controller-annotations:
743+
738744
You can also choose to install and use the optional ``SecurityExtraBundle``,
739745
which can secure your controller using annotations:
740746

book/service_container.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,8 @@ the service itself gets loaded. To do so, you can use the ``file`` directive.
946946
Notice that symfony will internally call the PHP function require_once
947947
which means that your file will be included only once per request.
948948

949+
.. _book-service-container-tags:
950+
949951
Tags (``tags``)
950952
~~~~~~~~~~~~~~~
951953

Lines changed: 82 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
How to secure any Service or Method in your Application
22
=======================================================
33

4-
In the :doc:`/book/security` book pages you can see how to secure
5-
``ContainerAware`` controllers by requesting the ``security.context`` service
6-
from the Service Container and checking the current user's role:
7-
8-
.. code-block:: php
4+
In the security chapter, you can see how to :ref:`secure a controller<book-security-securing-controller>`
5+
by requesting the ``security.context`` service from the Service Container
6+
and checking the current user's role::
97

108
use Symfony\Component\Security\Core\Exception\AccessDeniedException
119
// ...
@@ -19,12 +17,12 @@ from the Service Container and checking the current user's role:
1917
// ...
2018
}
2119

22-
You can also secure any service in a similar way by injecting the
23-
``security.context`` service into it. For a general introduction to injecting
24-
dependencies into services see the :doc:`/book/service_container` chapter of
25-
the book. For example, you have a ``NewsletterManager`` class for sending out
26-
newsletters and want to restrict its use to only users with the
27-
``ROLE_NEWSLETTER_ADMIN`` role. The class currently looks like this:
20+
You can also secure *any* service in a similar way by injecting the ``security.context``
21+
service into it. For a general introduction to injecting dependencies into
22+
services see the :doc:`/book/service_container` chapter of the book. For
23+
example, suppose you have a ``NewsletterManager`` class that sends out emails
24+
and you want to restrict its use to only users who have some ``ROLE_NEWSLETTER_ADMIN``
25+
role. Before you add security, the class looks something like this:
2826

2927
.. code-block:: php
3028
@@ -35,47 +33,46 @@ newsletters and want to restrict its use to only users with the
3533
3634
public function sendNewsletter()
3735
{
38-
//--
36+
// where you actually do the work
3937
}
4038
4139
// ...
4240
}
4341
44-
You want to check the user's role when the ``sendNewsletter()`` method is
42+
Your goal is to check the user's role when the ``sendNewsletter()`` method is
4543
called. The first step towards this is to inject the ``security.context``
46-
service into the object. As we require the service it is an ideal candidate
47-
for constructor injection as this makes it a required dependency:
48-
49-
.. code-block:: php
44+
service into the object. Since it won't make sense *not* to perform the security
45+
check, this is an ideal candidate for constructor injection, which guarantees
46+
that the security context object will be available inside the ``NewsletterManager``
47+
class::
5048

5149
namespace Acme\HelloBundle\Newsletter;
50+
51+
use Symfony\Component\Security\Core\SecurityContextInterface;
5252

5353
class NewsletterManager
5454
{
5555
protected $securityContext;
5656

57-
public function __construct($securityContext)
57+
public function __construct(SecurityContextInterface $securityContext)
5858
{
5959
$this->securityContext = $securityContext;
6060
}
6161

6262
// ...
6363
}
6464

65-
Then in your config you can inject the service:
65+
Then in your service configuration, you can inject the service:
6666

6767
.. configuration-block::
6868

6969
.. code-block:: yaml
7070
7171
# src/Acme/HelloBundle/Resources/config/services.yml
7272
parameters:
73-
# ...
7473
newsletter_manager.class: Acme\HelloBundle\Newsletter\NewsletterManager
7574
7675
services:
77-
my_mailer:
78-
# ...
7976
newsletter_manager:
8077
class: %newsletter_manager.class%
8178
arguments: [@security.context]
@@ -84,14 +81,10 @@ Then in your config you can inject the service:
8481
8582
<!-- src/Acme/HelloBundle/Resources/config/services.xml -->
8683
<parameters>
87-
<!-- ... -->
8884
<parameter key="newsletter_manager.class">Acme\HelloBundle\Newsletter\NewsletterManager</parameter>
8985
</parameters>
9086
9187
<services>
92-
<service id="my_mailer" ... >
93-
<!-- ... -->
94-
</service>
9588
<service id="newsletter_manager" class="%newsletter_manager.class%">
9689
<argument type="service" id="security.context"/>
9790
</service>
@@ -103,7 +96,6 @@ Then in your config you can inject the service:
10396
use Symfony\Component\DependencyInjection\Definition;
10497
use Symfony\Component\DependencyInjection\Reference;
10598
106-
// ...
10799
$container->setParameter('newsletter_manager.class', 'Acme\HelloBundle\Newsletter\NewsletterManager');
108100
109101
$container->setDefinition('newsletter_manager', new Definition(
@@ -112,21 +104,19 @@ Then in your config you can inject the service:
112104
));
113105
114106
The injected service can then be used to perform the security check when the
115-
``sendNewsletter()`` method is called:
116-
117-
.. code-block:: php::
107+
``sendNewsletter()`` method is called::
118108

119109
namespace Acme\HelloBundle\Newsletter;
120110

121111
use Symfony\Component\Security\Core\Exception\AccessDeniedException
122-
use Symfony\Component\Security\Core\SecurityContext;
112+
use Symfony\Component\Security\Core\SecurityContextInterface;
123113
// ...
124114

125115
class NewsletterManager
126116
{
127117
protected $securityContext;
128118

129-
public function __construct(SecurityContext $securityContext)
119+
public function __construct(SecurityContextInterface $securityContext)
130120
{
131121
$this->securityContext = $securityContext;
132122
}
@@ -143,80 +133,42 @@ The injected service can then be used to perform the security check when the
143133
// ...
144134
}
145135

146-
If the current user does not have the ``ROLE_NEWSLETTER_ADMIN`` then they
147-
will be prompted to log in.
136+
If the current user does not have the ``ROLE_NEWSLETTER_ADMIN``, they will
137+
be prompted to log in.
148138

149139
Securing Methods Using Annotations
150-
~~~~~~~~~~~~~~~~~~~~~~~~~~
140+
----------------------------------
151141

152-
You can also secure method calls in any service using annotations using the
153-
``SecurityExtraBundle`` optional bundle. This is included in the standard
154-
Symfony2 distribution. The default configuration for the
155-
``SecurityExtraBundle`` only secures Controllers and not all services:
142+
You can also secure method calls in any service with annotations by using the
143+
optional `SecurityExtraBundle`_ bundle. This bundle is included in the Symfony2
144+
Standard Distribution.
156145

157-
.. configuration-block::
158-
159-
.. code-block:: yaml
160-
161-
# app/config/config.yml
162-
jms_security_extra:
163-
secure_controllers: true
164-
secure_all_services: false
165-
166-
.. code-block:: xml
167-
168-
<!-- app/config/config.xml -->
169-
<srv:container xmlns="http://symfony.com/schema/dic/security"
170-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
171-
xmlns:srv="http://symfony.com/schema/dic/services"
172-
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
173-
174-
<jms_security_extra secure_controllers="true"secure_all_services="true" />
175-
176-
</srv:container>
177-
178-
.. code-block:: php
179-
180-
// app/config/config.php
181-
$container->loadFromExtension('jms_security_extra', array(
182-
'secure_controllers' => true,
183-
'secure_all_services' => false,
184-
));
185-
186-
To use annotations to secure other services you can set ``secure_all_services``
187-
to true. Alternatively you can specify individual services to secure by tagging
188-
them with ``security.secure_service``:
146+
To enable the annotations functionality, :ref:`tag<book-service-container-tags>`
147+
the service you want to secure with the ``security.secure_service`` tag
148+
(you can also automatically enable this functionality for all services, see
149+
the :ref:`sidebar<securing-services-annotations-sidebar>` below):
189150

190151
.. configuration-block::
191152

192153
.. code-block:: yaml
193154
194155
# src/Acme/HelloBundle/Resources/config/services.yml
195-
parameters:
196-
# ...
197-
newsletter_manager.class: Acme\HelloBundle\Newsletter\NewsletterManager
156+
# ...
198157
199158
services:
200-
my_mailer:
201-
# ...
202159
newsletter_manager:
203-
class: %newsletter_manager.class%
160+
# ...
204161
tags:
205162
- { name: security.secure_service }
206163
207164
.. code-block:: xml
208165
209166
<!-- src/Acme/HelloBundle/Resources/config/services.xml -->
210-
<parameters>
211-
<!-- ... -->
212-
<parameter key="newsletter_manager.class">Acme\HelloBundle\Newsletter\NewsletterManager</parameter>
213-
</parameters>
167+
<!-- ... -->
214168
215169
<services>
216-
<service id="my_mailer" ... >
217-
<!-- ... -->
218-
</service>
219170
<service id="newsletter_manager" class="%newsletter_manager.class%">
171+
<!-- ... -->
220172
<tag name="security.secure_service" />
221173
</service>
222174
</services>
@@ -227,16 +179,14 @@ them with ``security.secure_service``:
227179
use Symfony\Component\DependencyInjection\Definition;
228180
use Symfony\Component\DependencyInjection\Reference;
229181
230-
// ...
231-
$container->setParameter('newsletter_manager.class', 'Acme\HelloBundle\Newsletter\NewsletterManager');
232-
233-
$definition = new Definition('%newsletter_manager.class%');
182+
$definition = new Definition(
183+
'%newsletter_manager.class%',
184+
array(new Reference('security.context'))
185+
));
234186
$definition->addTag('security.secure_service');
235187
$container->setDefinition('newsletter_manager', $definition);
236188
237-
You can then achieve the same results as above using an annotation:
238-
239-
.. code-block:: php::
189+
You can then achieve the same results as above using an annotation::
240190

241191
namespace Acme\HelloBundle\Newsletter;
242192

@@ -268,4 +218,45 @@ The ``SecurityExtraBundle`` also allows you to secure the parameters and return
268218
values of methods. For more information, see the `SecurityExtraBundle`_
269219
documentation.
270220

221+
.. _securing-services-annotations-sidebar:
222+
223+
.. sidebar:: Activating the Annotations Functionality for all Services
224+
225+
When securing the method of a service (as shown above), you can either
226+
tag each service individually, or activate the functionality for *all*
227+
services at once. To do so, set the ``secure_all_services`` configuration
228+
option to true:
229+
230+
.. configuration-block::
231+
232+
.. code-block:: yaml
233+
234+
# app/config/config.yml
235+
jms_security_extra:
236+
# ...
237+
secure_all_services: false
238+
239+
.. code-block:: xml
240+
241+
<!-- app/config/config.xml -->
242+
<srv:container xmlns="http://symfony.com/schema/dic/security"
243+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
244+
xmlns:srv="http://symfony.com/schema/dic/services"
245+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
246+
247+
<jms_security_extra secure_controllers="true" secure_all_services="true" />
248+
249+
</srv:container>
250+
251+
.. code-block:: php
252+
253+
// app/config/config.php
254+
$container->loadFromExtension('jms_security_extra', array(
255+
// ...
256+
'secure_all_services' => false,
257+
));
258+
259+
The disadvantage of this method is that, if activated, the initial page
260+
load may be very slow depending on how many services you have defined.
261+
271262
.. _`SecurityExtraBundle`: https://github.com/schmittjoh/SecurityExtraBundle

0 commit comments

Comments
 (0)
0