Skip to content

Access control #3339

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 26, 2013
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Created consolidated "Access control" section; added warning about ro…
…uting error pages
  • Loading branch information
romaricdrigon committed Dec 20, 2013
commit 808d055690c57d917672f45c318bff856479d687
228 changes: 110 additions & 118 deletions book/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,11 @@ see :doc:`/cookbook/security/form_login`.
for different firewalls. But usually for most applications, having one
main firewall is enough.

**5. Routing error pages are not covered by firewalls**

As Routing is done *before* security, Routing error pages are not covered
by any firewall.

Authorization
-------------

Expand Down Expand Up @@ -1000,73 +1005,6 @@ the user will be redirected to ``https``:
),
),

.. _book-security-securing-controller:

Securing a Controller
~~~~~~~~~~~~~~~~~~~~~

Protecting your application based on URL patterns is easy, but may not be
fine-grained enough in certain cases. When necessary, you can easily force
authorization from inside a controller::

// ...
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

public function helloAction($name)
{
if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) {
throw new AccessDeniedException();
}

// ...
}

.. _book-security-securing-controller-annotations:

You can also choose to install and use the optional JMSSecurityExtraBundle,
which can secure your controller using annotations::

// ...
use JMS\SecurityExtraBundle\Annotation\Secure;

/**
* @Secure(roles="ROLE_ADMIN")
*/
public function helloAction($name)
{
// ...
}

For more information, see the `JMSSecurityExtraBundle`_ documentation.

Securing other Services
~~~~~~~~~~~~~~~~~~~~~~~

In fact, anything in Symfony can be protected using a strategy similar to
the one seen in the previous section. For example, suppose you have a service
(i.e. a PHP class) whose job is to send emails from one user to another.
You can restrict use of this class - no matter where it's being used from -
to users that have a specific role.

For more information on how you can use the Security component to secure
different services and methods in your application, see :doc:`/cookbook/security/securing_services`.

Access Control Lists (ACLs): Securing Individual Database Objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Imagine you are designing a blog system where your users can comment on your
posts. Now, you want a user to be able to edit their own comments, but not
those of other users. Also, as the admin user, you yourself want to be able
to edit *all* comments.

The Security component comes with an optional access control list (ACL) system
that you can use when you need to control access to individual instances
of an object in your system. *Without* ACL, you can secure your system so that
only certain users can edit blog comments in general. But *with* ACL, you
can restrict or allow access on a comment-by-comment basis.

For more information, see the cookbook article: :doc:`/cookbook/security/acl`.

Users
-----

Expand Down Expand Up @@ -1711,6 +1649,111 @@ In the above configuration, users with ``ROLE_ADMIN`` role will also have the
``ROLE_USER`` role. The ``ROLE_SUPER_ADMIN`` role has ``ROLE_ADMIN``, ``ROLE_ALLOWED_TO_SWITCH``
and ``ROLE_USER`` (inherited from ``ROLE_ADMIN``).

Access Control
--------------

Now that you have Users and Roles, you can go further than URL patterns based authorization.

.. _book-security-securing-controller:

Access Control in Controllers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Protecting your application based on URL patterns is easy, but may not be
fine-grained enough in certain cases. When necessary, you can easily force
authorization from inside a controller::

// ...
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

public function helloAction($name)
{
if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) {
throw new AccessDeniedException();
}

// ...
}

.. caution::

A firewall must be active or an exception will be thrown when the ``isGranted()``
method is called. It's almost always a good idea to have a main firewall that
covers all URLs (as it has been shown in this chapter).

.. _book-security-securing-controller-annotations:

You can also choose to install and use the optional `JMSSecurityExtraBundle`_,
which can secure your controller using annotations::

// ...
use JMS\SecurityExtraBundle\Annotation\Secure;

/**
* @Secure(roles="ROLE_ADMIN")
*/
public function helloAction($name)
{
// ...
}

Access Control in Other Services
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In fact, anything in Symfony can be protected using a strategy similar to
the one seen in the previous section. For example, suppose you have a service
(i.e. a PHP class) whose job is to send emails from one user to another.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't it be which instead of whose?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a job of the service, so it should be "whose" imo, but let's wait what our native thinks :)

You can restrict use of this class - no matter where it's being used from -
to users that have a specific role.

For more information on how you can use the Security component to secure
different services and methods in your application, see :doc:`/cookbook/security/securing_services`.

.. _book-security-template:

Access Control in Templates
~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you want to check if the current user has a role inside a template, use
the built-in helper function:

.. configuration-block::

.. code-block:: html+jinja

{% if is_granted('ROLE_ADMIN') %}
<a href="...">Delete</a>
{% endif %}

.. code-block:: html+php

<?php if ($view['security']->isGranted('ROLE_ADMIN')): ?>
<a href="...">Delete</a>
<?php endif; ?>

.. note::

If you use this function and are *not* at a URL behind a firewall
active, an exception will be thrown. Again, it's almost always a good
idea to have a main firewall that covers all URLs (as has been shown
in this chapter).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can extent this a little bit, also noting that this doesn't work for routing error pages, as routing is done before the security?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we're in the book, which is said to be read by newcomers, it sound like a good idea.

So I guess the best would be to add a note while the explaining how to put a of the "main firewall that covers all URLs"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it in the common pitfalls section. Could you please review it?


Access Control Lists (ACLs): Securing Individual Database Objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Imagine you are designing a blog system where your users can comment on your
posts. Now, you want a user to be able to edit their own comments, but not
those of other users. Also, as the admin user, you yourself want to be able
to edit *all* comments.

The Security component comes with an optional access control list (ACL) system
that you can use when you need to control access to individual instances
of an object in your system. *Without* ACL, you can secure your system so that
only certain users can edit blog comments in general. But *with* ACL, you
can restrict or allow access on a comment-by-comment basis.

For more information, see the cookbook article: :doc:`/cookbook/security/acl`.

Logging Out
-----------

Expand Down Expand Up @@ -1822,57 +1865,6 @@ is defined by the ``target`` parameter above (e.g. the ``homepage``). For
more information on configuring the logout, see the
:doc:`Security Configuration Reference </reference/configuration/security>`.

.. _book-security-template:

Access Control in Templates
---------------------------

If you want to check if the current user has a role inside a template, use
the built-in helper function:

.. configuration-block::

.. code-block:: html+jinja

{% if is_granted('ROLE_ADMIN') %}
<a href="...">Delete</a>
{% endif %}

.. code-block:: html+php

<?php if ($view['security']->isGranted('ROLE_ADMIN')): ?>
<a href="...">Delete</a>
<?php endif; ?>

.. note::

If you use this function and are *not* at a URL where there is a firewall
active, an exception will be thrown. Again, it's almost always a good
idea to have a main firewall that covers all URLs (as has been shown
in this chapter).

Access Control in Controllers
-----------------------------

If you want to check if the current user has a role in your controller, use
the :method:`Symfony\\Component\\Security\\Core\\SecurityContext::isGranted`
method of the security context::

public function indexAction()
{
// show different content to admin users
if ($this->get('security.context')->isGranted('ROLE_ADMIN')) {
// ... load admin content here
}

// ... load other regular content here
}

.. note::

A firewall must be active or an exception will be thrown when the ``isGranted``
method is called. See the note above about templates for more details.

Impersonating a User
--------------------

Expand Down