Deepdive into the symfony2 security component: part 1

Warning: This blogpost has been posted over two years ago. That is a long time in development-world! The story here may not be relevant, complete or secure. Code might not be complete or obsoleted, and even my current vision might have (completely) changed on the subject. So please do read further, but use it with caution.
Posted on 19 Oct 2014
Tagged with: [ deepdive ]  [ PHP ]  [ security ]  [ symfony2

Once in a while I like diving into code and see how things work under the hood. And as the symfony2 framework consists of many different components, bundles and bridges, there is a lot to discover. But ultimately, the code itself mostly isn’t really as complex as it might seem from the outside world: just like a good magic trick, once unraveled, it all seems very simple and makes sense.

However, this is not true for one of those components: the security component. This black box full of dark magic doesn’t like to give up its secrets, and after some (miserably) failed attempts, I am trying to unravel it once more in a few blog posts. Either we achieve complete victory, or fail yet again.. At this point, I will give both fair odds.

Note that this blogpost are in the first place written for me personally. There may (and probably will) other blogposts be out there detailing the component, but I’d rather discover and share the experiences myself. Assumptions I make, may or may not be valid and might not even make sense, but then again, these posts should be considered as a learning process, not a hard truth (which I will never pretend I will have on anything).

About the security component

First, let’s talk about what the security component is. As taken from the symfony2 website:

The Security component provides a complete security system for your web application. It ships with facilities for authenticating using HTTP basic or digest authentication, interactive form login or X.509 certificate login, but also allows you to implement your own authentication strategies. Furthermore, the component provides ways to authorize authenticated users based on their roles, and it contains an advanced ACL system.

So it mainly does two things: authentication and authorization. Authentication is the thing where we figure out *WHO  a user is (for which he/she needs to give proof, like a password, a token or a certificate etc). The authorization part is where we figure out **WHAT a user is allowed to do. Maybe a user identified as “john doe” may look at a blog post, but is not allowed to edit this, while another user “ima admin”, is allowed to view, edit and even delete the same blogpost.

For the purpose of the rest of these articles, I will be using the 2.5 version of symfony. Some improvements / changes have been made in the upcoming symfony 2.6 version, and where I know of them, I’ll try and highlight them.

But when talking about the security inside Symfony2, we need to broaden our horizon than just looking at the security component alone. There are more things involved that makes Symfony2’s security work.

1. The security component

This is the “meat” of the security. Most magic will happen here and is / should be framework agnostic (you should be able to use this component inside your own projects, inside laravel, even inside Zend Framework 2 without too much effort). Even though most of the work will be done here, much of what we as symfony2 developers will actually see, will happen outside it.

2. The security bundle

The security bundle can be seen as the “glue” that makes the security component work inside the framework. If you were to use the security component into another framework, this part is what needs to be created. One of the things this bundle does, is configuring the security component through the standard configuration mechanisms (it will read the “security” section from your configuration that is normally located in app/config/security.yml, which gets imported through app/config/config.yml). But lots more will happen, especially through services.

3. Security bridges

One of the things that makes Symfony2 so great is that most bundles don’t rely on other bundles. For instance, it is possible to have users stored inside a database. This would mean we need to have a database connection which is normally done through doctrine. But the thing is: not everybody uses databases (or even if they do, maybe not doctrine) so it would be unwise to have the security bundle rely on the doctrine bundle. We don’t want “doctrine” code polluting our security bundle.

So where do we store the code that let these users to be stored and loaded from doctrine? Inside the doctrine bundle? This would result in the same issue: we would pollute the doctrine bundle with security code.

A lot of times it happens that we have code that connects bundle X to bundle Y, but it doesn’t really belong in bundle X, and doesn’t really belong in bundle Y. For this kind of code, symfony has so-called “bridges” (but this concept is obviously not specific for symfony).

If you take a look in the doctrine bridge, you’ll see that it contains a directory named “security”. Herein lies code that form the actual bridge between doctrine and security. This is (and should be) the ONLY place where the system depends on both the doctrine and the security bundles / components. (And yes, I guess it could also have been a security bridge, with a “doctrine” directory).

But as said, not everybody only uses doctrine with symfony. Propel is still an alternative to use which is why there is also a propel / security bridge inside symfony.

So these bridges allow us to use additional functionality without cluttering up the main bundles and components.

But if you look closely inside the security bundle, you’ll see that the bundle DOES rely on another component besides the security component, namely twig. Inside the bundle there is an extension created for twig in order to add some additional twig functions that can be used. Personally, it would make a bit more sense to move this into the Twig bridge which funny enough already got some security code. However, the security bundle CAN still function properly without twig present, as the twig code just won’t be called (but it’s a “hard” dependency nevertheless).

So as said, the third bridge that is available in a standard symfony2 framework setup is a twig bridge that provides a simple extension that allows you to check for user authorizations within your twig templates.

Update

After some initial work on this series, I’ve decided to turn this into an actual book. The reason: it’s WAY too much to address in a simple blog post series. So much actually, that the book itself is a whopping 234 pages full of details about the Security component of Symfony.

If you are interested, you can download the free sample, or buy the whole book from leanpub: https://leanpub.com/symfonyframeworkdeepdive-security


Did you find this blogpost interesting?

Check out the security edition of the Symfony Rainbow Deepdive series! It contains an in-depth explanation of the Security component, the different bundles and bridges and detailed explaination of all configuration options.

The book, and free sample book are available as PDF, EPUB and MOBI on Leanpub: https://leanpub.com/symfonyframeworkdeepdive-security.