Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

composer require security

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Welcome back friends! I'm so happy that you've stumbled into my Symfony 5 security tutorial for a bunch of reasons. The first is that well... uh... the site that we've been building has NO security... and the raptors are starting to jiggle the door handles.

The other reason is that, once we make it to the maintenance shed on other side of the compound, we're going to explore Symfony's new security system, called the "authenticator" system. Ooh. If you've used the old system, you'll feel right at home. If you're new to Symfony security, you chose a great time to start. The new system is easier to learn and understand... but it's also more powerful.

Project Setup

And because the security system isn't going to come online by itself, let's get to work. To learn how to authenticate & authorize & do other cool security stuff at a pro level, you should definitely download the course code from this page and code along with me. Making real-world mistakes.... yeah, it's the best way to remember this stuff.

After unzipping the file, you'll find a start/ directory with the same code that you see here. Pop open the README.md file for all the setup instructions. The last step will be to find a terminal, move into the project and start a web server. I'm going to use the symfony binary for this:

symfony serve -d

This starts up a new server at https://127.0.0.1:8000. Open that in your browser... or be lazy and run:

symfony open:local

to... "delegate" the work to someone else. Say hello to Cauldron Overflow! A question and answer site for witches and wizards, who... unfortunately... keep casting their spells live on production first without testing them... and usually on a Friday afternoon. Sheesh. Then they come here to ask how to undo the damage.

Installing Security

Because Symfony's philosophy is to start small and then allow you to install the stuff you need later, right now our app... literally does not have a security system.

That's no fun, so let's install one! Go back to your terminal and run:

composer require security

This installs Symfony's security bundle. After it finishes... run:

git status

to see what its recipe did. In addition to the normal stuff, it added one new configuration file: security.yaml. Let's go check that out: config/packages/security.yaml:

security:
# https://symfony.com/doc/current/security/authenticator_manager.html
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#c-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
users_in_memory: { memory: null }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: users_in_memory
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }

As you hopefully guessed by its name, this file powers the security system! By the time we're done, each section in here will be simple and boring to you. I love when programming stuff is boring.

enable_authenticator_manager

Oh, but see this enable_authenticator_manager key?

security:
# https://symfony.com/doc/current/security/authenticator_manager.html
enable_authenticator_manager: true
... lines 4 - 29

In Symfony 5.3 - the version I'm using - the old and new security systems live side-by-side and you get to choose which one you want! When you set enable_authenticator_manager to true, you are activating the new system. Yay! Shiny! If you're working on a legacy project and need to learn the old system, check out our Symfony 4 Security tutorial. It's pretty cool too!

Authentication & Authorization

Anyways, when you talk about security, there are two big parts: authentication and authorization. Authentication asks the question, "who are you"? And "can you prove it?" Users, login forms, remember me cookies, passwords, API keys... all of that stuff is related to authentication.

Authorization asks a different question: "Should you have access to this resource?" Authorization doesn't care much about who you are... it's all about allowing or denying access to different things, like different URLs or controllers.

In Symfony, or really in any security system, authentication is the tricky part. I mean, just think about how many ways there are to authenticate! Login forms, API token authentication, social authentication with OAuth, SSO's, LDAP, putting on a fake mustache and walking confidently passed a security guard. I mean... the possibilities are endless. But I also think that authentication is super fun.

So next: let's start on our journey into the new shiny authenticator system by creating the most basic part of authentication: a user class.

Leave a comment!

18
Login or Register to join the conversation
davidmintz Avatar
davidmintz Avatar davidmintz | posted 8 months ago

I'm happy to report solutions to a problem some people may encounter. If you are running PHP 8.1, composer cannot install.

You can install php-fpm7.4 or 8.0 alongside php-fpm8.1 on the same machine and use update-alternatives (on Debian-ish systems) to switch php versions, and this seems a sane option. I have done this to roll back to 8.0 and it works fine.

Another alternative is to use Devilbox It's a little more involved, but it's kind of cool.

Reply

Hi David Mintz

Another workaround will be to update

laminas/laminas-code

package to unblock php 8.1
So you can install everything with

composer update laminas/laminas-code command

Cheers! and thanks again for the reporting
Reply

Hey David,

Thank you for reporting this! We will take a look at the course code and probably apply some fixes to make it possible to run the code on PHP 8.1

And thanks for the tips on how to workaround this problem!

Cheers!

Reply
Oliver W. Avatar
Oliver W. Avatar Oliver W. | posted 8 months ago

Hi,

any idea why I get "an error occured while loading the web debug toolbar" from the very beginning? The page itself is displayed but no debug toolbar.

I alreday cleared the diretory vendor\cache. No changes.
Ah, I even tried do download the code once again today. No changes.
Trying to open /answers/popular brings an 404.

Starting composer require annotations brings no changes.

What else can I look for?

By the way: I am working on a local XAMPP. But in other projects the debug toolbar works fine.

Thx
Oliver

Reply
Oliver W. Avatar

got it: it's that weird thing called .htaccess.

Reply

Hey Oliver,

Oh, yeah, it might be .htaccess. I'd recommend you to use Symfony's built-in server for developing purposes locally, but if you do want to use XAMPP that runs real Apache web server - I'd advice you to install "symfony/apache-pack" dependency that will bring the default Symfony .htaccess into your project, though you might still want to tweak it, depends on your local configuration.

I hope this helps!

Cheers!

1 Reply
chessserver Avatar
chessserver Avatar chessserver | posted 8 months ago

Is there a guide or howto or something similar which explains the migration from GuardAuthentication to the new system? It seems that it runs on Symfony 5.4, but won´t with Symfony 6 (that is my understanding). Can you add one or two lessons about the migration?

Reply
Oliver W. Avatar
Oliver W. Avatar Oliver W. | posted 8 months ago

Hi,

when trying to runsymfony console doctrine:migrations:migrate I keep getting this as error:

[notice] Migrating up to DoctrineMigrations\Version20210907192620

[error] Migration DoctrineMigrations\Version20210902182514 failed during Execution. Error: "An exception occurred while executing 'ALTER TABLE answer RENAME INDEX idx_9474526c1e27f6bf TO IDX_DADD4A251E27F6BF':

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INDEX idx_9474526c1e27f6bf TO IDX_DADD4A251E27F6BF' at line 1"

In AbstractMySQLDriver.php line 98:

An exception occurred while executing 'ALTER TABLE answer RENAME INDEX idx_9474526c1e27f6bf TO IDX_DADD4A251E27F6BF':

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INDEX idx_9474526c1e27f6bf TO IDX_

DADD4A251E27F6BF' at line 1

I am working with XAMPP with PHP 7.4.9 and MariaDB 10.4.14. In my .env i noted ...serverVerion=mariadb-10.4.14 which works fine for other Smyfony projects.

By the way: when submitting ALTER TABLE answer RENAME INDEX idx_..... directly on the server it tells me that a comma is missing just before start of a new alter operation (near "TO")!?!?!?

What goes wrong?

Thx
Oliver

Reply

Hey Oliver Wagner

Your version of MariaDB does not allow to rename an index, here's a related issue to your problem https://github.com/PomeloFo...

You can tweak the query to regenerate the index instead, or, you could upgrade your database version, I believe the "RENAME INDEX" operation is supported by the latest MariaDB version

Cheers!

Reply
Oliver W. Avatar

thx, I've been changing the name of the idex manually and manipulated the migrations table. So it finally worked.

Reply
Christopher S. Avatar
Christopher S. Avatar Christopher S. | posted 10 months ago

Hi, I've tried setting up the project like the readme describes. I'm able to start the docker, but when I want to create a database using the symfony console command I get "SQLSTATE[HY000] [2002] Connection refused" as a response in the console.

Reply

Hey Daniel,

Please, double check your DB credentials in .env and .env.local files. Looks like they are not valid for your specific MySQL server. Tweak them to the correct ones and try again :)

Cheers!

Reply
Tomáš K. Avatar

Hi Victor,

this could be an issue with the initial docker-compose.yaml file

I actually got the same error message as Daniel but I figured out that the issue might be about naming of the database service. In the pre-generated docker-compose.yaml the service name was secure_db, while on other projects I had database. By simply renaming the service, removing and restarting the docker container and clearing symfony cache i got it work.

Reply

Hey Tomik!

Thank you for the tips how to fix things!

Yeah, naming might be different on different courses, that's why we recommend to download a new course code and start coding with us from start/ directory. Except some naming things, we may add more changes between courses, like upgrading dependencies, slightly changing code to have better use cases that we will cover in the videos, etc. So, if you continue the course code from a past tutorial, you may have differences between your code after a past tutorial and the code we show in the new course.

Cheers!

2 Reply
Art A. Avatar

I'm using symfony 5.2 whit two type authentication using email & password and google oAuth. When I enable enable_authenticator_manager=true it comes out the error: 'you can not user enable_authenticator_manager with oAuth'. Not sure why enable_authenticator_manager does not work with oAuth

Reply

Hey artan!

What bundle are you using that gives you the OAuth support? Bundles need to add support for the new "authenticator" system. It's actually quite easy... but if the bundle hasn't done it yet, then it needs to :).

Cheers!

Reply
Jf senechal Avatar
Jf senechal Avatar Jf senechal | posted 11 months ago

There is a small typo : require and not requires ;-)

Reply

Hey Jf,

Thanks for reporting this! I fixed this misprint in https://github.com/SymfonyC...

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial also works great for Symfony 6!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.4.1 || ^8.0.0",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "babdev/pagerfanta-bundle": "^3.3", // v3.3.0
        "composer/package-versions-deprecated": "^1.11", // 1.11.99.4
        "doctrine/annotations": "^1.0", // 1.13.2
        "doctrine/doctrine-bundle": "^2.1", // 2.6.3
        "doctrine/doctrine-migrations-bundle": "^3.0", // 3.1.1
        "doctrine/orm": "^2.7", // 2.10.1
        "knplabs/knp-markdown-bundle": "^1.8", // 1.9.0
        "knplabs/knp-time-bundle": "^1.11", // v1.16.1
        "pagerfanta/doctrine-orm-adapter": "^3.3", // v3.3.0
        "pagerfanta/twig": "^3.3", // v3.3.0
        "phpdocumentor/reflection-docblock": "^5.2", // 5.2.2
        "scheb/2fa-bundle": "^5.12", // v5.12.1
        "scheb/2fa-qr-code": "^5.12", // v5.12.1
        "scheb/2fa-totp": "^5.12", // v5.12.1
        "sensio/framework-extra-bundle": "^6.0", // v6.2.0
        "stof/doctrine-extensions-bundle": "^1.4", // v1.6.0
        "symfony/asset": "5.3.*", // v5.3.4
        "symfony/console": "5.3.*", // v5.3.7
        "symfony/dotenv": "5.3.*", // v5.3.8
        "symfony/flex": "^1.3.1", // v1.17.5
        "symfony/form": "5.3.*", // v5.3.8
        "symfony/framework-bundle": "5.3.*", // v5.3.8
        "symfony/monolog-bundle": "^3.0", // v3.7.0
        "symfony/property-access": "5.3.*", // v5.3.8
        "symfony/property-info": "5.3.*", // v5.3.8
        "symfony/rate-limiter": "5.3.*", // v5.3.4
        "symfony/runtime": "5.3.*", // v5.3.4
        "symfony/security-bundle": "5.3.*", // v5.3.8
        "symfony/serializer": "5.3.*", // v5.3.8
        "symfony/stopwatch": "5.3.*", // v5.3.4
        "symfony/twig-bundle": "5.3.*", // v5.3.4
        "symfony/ux-chartjs": "^1.3", // v1.3.0
        "symfony/validator": "5.3.*", // v5.3.8
        "symfony/webpack-encore-bundle": "^1.7", // v1.12.0
        "symfony/yaml": "5.3.*", // v5.3.6
        "symfonycasts/verify-email-bundle": "^1.5", // v1.5.0
        "twig/extra-bundle": "^2.12|^3.0", // v3.3.3
        "twig/string-extra": "^3.3", // v3.3.3
        "twig/twig": "^2.12|^3.0" // v3.3.3
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.3", // 3.4.0
        "symfony/debug-bundle": "5.3.*", // v5.3.4
        "symfony/maker-bundle": "^1.15", // v1.34.0
        "symfony/var-dumper": "5.3.*", // v5.3.8
        "symfony/web-profiler-bundle": "5.3.*", // v5.3.8
        "zenstruck/foundry": "^1.1" // v1.13.3
    }
}