Please note: I have revised this article to become part of the official documentation of the Security Component.

The Security Context

Central to the Security Component is the security context, which is an instance of SecurityContext. When all steps in the process of authenticating the user have been taken successfully, the security context may be asked if the authenticated user has access to a certain action or resource of the application.

use Symfony\Component\Security\SecurityContext;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

$context = new SecurityContext();

// authenticate the user...

if (!$context->isGranted('ROLE_ADMIN')) {
    throw new AccessDeniedException();
}

A firewall for HTTP requests

Authenticating a user is done by the firewall. An application may have multiple secured areas, so the firewall is configured using a map of these secured areas. For each of these areas, the map contains a request matcher and a collection of listeners. The request matcher gives the firewall the ability to find out if the current request points to a secured area. The listeners are then asked if the current request can be used to authenticate the user.

use Symfony\Component\Security\Http\FirewallMap;
use Symfony\Component\HttpFoundation\RequestMatcher;
use Symfony\Component\Security\Http\Firewall\ExceptionListener;

$map = new FirewallMap();

$requestMatcher = new RequestMatcher('^/secured-area/');

$listeners = array(
// ...
);
$exceptionListener = new ExceptionListener(/* ... */);

$map->add($requestMatcher, $listeners, $exceptionListener);

The firewall map will be given to the firewall as it's first argument, together with the event dispatcher that is used by the HttpKernel.

use Symfony\Component\Security\Http\Firewall;
use Symfony\Component\HttpKernel\KernelEvents;

// $dispatcher is the EventDispatcher used by the HttpKernel

$firewall = new Firewall($map, $dispatcher);

$dispatcher->register(KernelEvents::REQUEST, array($firewall, 'onKernelRequest');

The firewall is registered to listen to the kernel.request event that will be dispatched by the HttpKernel at the beginning of each request it processes. This way, the firewall may prevent the user from going any further than allowed.

Firewall listeners

When the firewall gets notified of the kernel.request event, it asks the firewall map if the request matches any of the secured areas. If it does, the corresponding listeners (who each implement ListenerInterface) will be asked to handle the current request. This basically means: find out if the current request contains any information by which the user might be authenticated (for instance the Basic HTTP authentication listener checks if the request has a header called "PHP_AUTH_USER").

Exception listener

If any of the listeners throws an AuthenticationException (or any exception extending this exception), the exception listener that was provided when adding secured areas to the firewall map will jump in.

The exception listener determines what happens next, based on the arguments it received when it was created. It may start the authentication procedure, maybe ask the user to supply his credentials again (when he has only been authenticated based on a "remember-me" cookie), or transform the exception into an AccessDeniedHttpException, which will eventually result in an "HTTP/1.1 401: Access Denied" response.

Entry points

When the user is not authenticated at all (i.e. when the security context has no token yet), the firewall's entry point will be called to "start" the authentication process. An entry point should implement AuthenticationEntryPointInterface, which has only one method: start(). This method receives the current Request object and the exception by which the exception listener was triggered. The method should return a Response object, for instance the page containing the login form, or in the case of Basic HTTP authentication a response with a "WWW-Authenticate" header, which will prompt the user to supply his username and password.

PHP Security Symfony2 documentation firewall
Comments
This website uses MailComments: you can send your comments to this post by email. Read more about MailComments, including suggestions for writing your comments (in HTML or Markdown).
Karol Sójko

An awesome read for today's morning. Great Job ! The second part as well :)

Matthias Noback

Thanks!

Greg

Why not send a PR to symfony-docs ? https://github.com/symfony/...

Matthias Noback

Hi Greg, I had in fact done that already: https://github.com/symfony/... Yet, I think that publishing it here could attract more reviewers.

Greg

sorry. I did not see the PR.

victor

Hi Matthias,

Thanks for taking the time to write some documentation.

The first code excerpt (The Security Context) seems to be the wrong one (same as the second excerpt).

May be you could also describe how entry points are trigerred in the "Entry points" section.

Overall the post is clear and help understanding the basic blocks.

Matthias Noback

Hi Victor,
And thanks for reading it carefully :) I corrected my mistake just now. Thanks for your suggestion about entry points.