Chapters
33 Chapters
|
3:34:13
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3
Subscribe to download the code!Compatible PHP versions: ^7.1.3
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
05.
Firewalls & Authenticator
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.10.2
"doctrine/doctrine-bundle": "^1.6.10", // 1.10.2
"doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // v2.0.0
"doctrine/orm": "^2.5.11", // v2.7.2
"knplabs/knp-markdown-bundle": "^1.7", // 1.7.0
"knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
"knplabs/knp-time-bundle": "^1.8", // 1.8.0
"nexylan/slack-bundle": "^2.0,<2.2.0", // v2.0.0
"php-http/guzzle6-adapter": "^1.1", // v1.1.1
"phpdocumentor/reflection-docblock": "^3.0|^4.0", // 4.3.0
"sensio/framework-extra-bundle": "^5.1", // v5.2.0
"stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
"symfony/asset": "^4.0", // v4.1.4
"symfony/cache": "^3.3|^4.0", // v4.1.4
"symfony/console": "^4.0", // v4.1.4
"symfony/flex": "^1.0", // v1.21.6
"symfony/framework-bundle": "^4.0", // v4.1.4
"symfony/lts": "^4@dev", // dev-master
"symfony/property-access": "^3.3|^4.0", // v4.1.4
"symfony/property-info": "^3.3|^4.0", // v4.1.4
"symfony/security-bundle": "^4.0", // v4.1.4
"symfony/serializer": "^3.3|^4.0", // v4.1.4
"symfony/twig-bundle": "^4.0", // v4.1.4
"symfony/web-server-bundle": "^4.0", // v4.1.4
"symfony/yaml": "^4.0", // v4.1.4
"twig/extensions": "^1.5" // v1.5.2
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0", // 3.0.2
"easycorp/easy-log-handler": "^1.0.2", // v1.0.7
"fzaninotto/faker": "^1.7", // v1.8.0
"symfony/debug-bundle": "^3.3|^4.0", // v4.1.4
"symfony/dotenv": "^4.0", // v4.1.4
"symfony/maker-bundle": "^1.0", // v1.7.0
"symfony/monolog-bundle": "^3.0", // v3.3.0
"symfony/phpunit-bridge": "^3.3|^4.0", // v4.1.4
"symfony/stopwatch": "^3.3|^4.0", // v4.1.4
"symfony/var-dumper": "^3.3|^4.0", // v4.1.4
"symfony/web-profiler-bundle": "^3.3|^4.0" // v4.1.4
}
}
34 Comments
Somehow "Under the main firewall, add a new guard key, a new authenticators key below that, and add one item in that array: App\Security\LoginFormAuthenticator:" was automagically done for me probably during "make:auth" here? https://github.com/symfony/... I did originally choose the "Login form authenticator" option but cancelled it before answering "The class name of the authenticator to create (e.g. AppCustomAuthenticator):".
Hey Alex,
Most probably so, "make:auth" command might become smarter in your version of MakerBundle :)
Cheers!
Hi, I've been digging through Symfony's source code over the past few hours trying to answer a pretty simple question - are ROLE_'s case sensitive? I've noticed in my app that both ROLE_Admin and ROLE_ADMIN both work, so I'm guessing role names are case insensitive, but the convention is to specify them as upper case with underscores between words. We have our projects setup to take roles from SAML attributes, one being "Admin", which we transform into ROLE_<saml_role_name> (ie. ROLE_Admin, in this case). So is ROLE_ADMIN and ROLE_Admin two separate roles from Symfony's point of view, or are they the same?
Hey Nathan,
Good question! I always thought they should be case sensitive, but if you say that both work for you - maybe they are not case sensitive. Or, it may depend on Symfony version. Or it may just work in some spots and does not work others :) But you're right, the convention is to always uppercase them. About the code, I believe the logic lives in RoleVoter: https://github.com/symfony/... - as you can see it clearly compare strings with strict ===, so I would say different cases won't work... unless you wrote it as ROLE_Admin in all spots that will give you check like "ROLE_Admin" === "ROLE_Admin" there :)
I hope this helps!
Cheers!
Hi, will nice if you're mention in video..not sure from version.. but i see that in my case since 5.3+ lots of changes in security bundle.. no longer is in security.yaml the guard: but there is custom_authenticator: https://symfony.com/doc/cur...
+ also in Sf 5.3+ if i put inside public function supports die('Our authenticator is alive!'); i am getting compile error: about that it requires return bool from AbstractLoginFormAuthenticator
update: i found nice blog which explain everything https://smaine-milianni.med...
Hey Miky
Yeah that's true Symfony 5.3 has a lot of changes in Security component, and it can't be covered by some notes and honestly is not related to this tutorial 'cause it based on Symfony 4.
PS There will be a course dedicated to Symfony 5 + Security component, but I can't say any eta on it :)
Cheers!
I don't understand why Symfony allow many firewall and use only one (the first in security.yml file).
Also i discovered that when we put a pattern, something like
pattern: ^/(_(profiler|wdt)|css|images|js)/The firewall is absent(ignored?) in Symfony Profiler
Cheers!
Hey Helmis D.!
It's a good question - I was just talking about this exact thing with a friend last night :).
Inside your code (like a controller), you often write code like
$this->getUser()to find the ONE user that the "person" using your site is currently authenticated as. The "main" reason to have two firewalls is that it allows you to be logged in as two users at the same time. For example, suppose you have a firewall that matches^/adminand so when you are under /admin you log in as some "admin" user. But for any other URL on the site, you log in using some different "frontend" account. It's not a common use-case... so it's a bit hard to imagine (I would normally recommend that you have just one user and give some users admin rights to be able to access things under /admin).The point is, if you are logged in as some AdminUser and also FrontendUser, when you call
$this->getUser(), which one should be returned? In Symfony's security, for each request, you can only be authenticated as a single user. That's why, when the request starts, Symfony finds the one firewall that should be active and asks it "who is logged in?". So if you called$this->getUser()from a URL starting with /admin, you would get that AdminUser. And if you ran that same code on any other URL, you would get the FrontendUser.That's the long... description. Most of the time, you do not need multiple firewalls (not counting the fake "dev" firewall). Inside a single firewall, you can allow the user to authenticate in as many ways as you want - like a login form, API token header, LDAP, anything. Basically, the user can then choose how to log in. But ultimately, in your code when you call
$this->getUser(), you don't care how they logged in (e.g. LDAP) - you just care who they are.That's correct! Very good attention to detail. If the one firewall that's activated has
security: falseit basically disables the security system entirely. If that's a problem, just remove this firewall. The only reason it exists is to help prevent people from accidentally making their app security so tight that they accidentally require authentication for URLs starting with /_profile or /_wdt... which would break the profiler and web debug toolbar... and would probably be difficult to debug. If you know what you're doing and (for some reason) want security active on the profiler, you can totally remove this and take control.Does that help? Is there a use-case that is making you want to use multiple firewalls?
Cheers!
Thank you very much for taking the time for these explanations, I now understand how the firewall works. The ambiguities have disappeared from my head :D ☀
When using the 4.4 version of SecurityBundle, it looks like the main firewall defaults to "anonymous: lazy" rather than "anonymous: true" in security.yaml. I'm not sure if that's relevant or not, but I thought I would put it out there.
Hey Patrick!
Yeah, good catch! In practice (starting with 4.4.1 and 5.0.1 where a fix was done), "anonymous: lazy" should not behave in any noticeably different way than "anonymous: true". So it should be not a big deal - it's basically the same (lazy basically is the same as true). Thank you for mention it here!
Cheers!
HI! I would like to do my login form accessible in every page, like with a javascript pop-up instead of a login page, how could I manage the request in the controller if I did something like that?
Hint:
I get the error:
Not configuring explicitly the provider for the "guard" listener on "main" firewall is ambiguous as there is more than one registered provider.
The guard is set don't know why. Might be because I had previously install the FOS User Bundle? If it's the reason how can I remove it completly from symfony and make the project work again
Hey Gballocc7
To remove a bundle from a Symfony app is very easy, if you are using Symfony Flex all you need to do is remove it with composer, unless you added some specific config. The manual way would be to first remove the bundle from composer, remove the line of code which activates the bundle (inside bundles.php), then remove any config file and that would be it.
About your question. Have you checked this documentation? https://symfony.com/doc/cur...
Cheers!
Hi! Ihave this error:
The service "security.authentication.provider.guard.main" has a dependency on a non-existent service "App\Security\LoginFormAuthenticator".
The namespace is correct
Hey Roman R.!
Yep, I know this error! And you've already done the first thing correctly: double-check your namespace.
Basically, this error means that, for some reason, the App\Security\LoginFormAuthenticator service does not exist. Check the spelling of the "namespace" inside that class as well as the class name to be sure. Also, what version of Symfony are you using? If everything is setup correctly with this service, you should see it when you run:
Let me know what you find out - it's most likely a small typo somewhere!
Cheers!
Thank you for reply. I double check everything and there is no typo.If running that command the same error occured in console. I'm trying define authenticator as a service and in this case everything looks good but --debug:container --show-private authenticator show only this:
[0] maker.maker.make_authenticator
[1] Symfony\Component\Security\Guard\GuardAuthenticatorHandler
Hey Roman R.!
Hmm. Can you post your services.yaml code? And what version of Symfony are you using? I'm wondering if you're not using the new service auto-registration stuff and so you're using a different service id. Let me know :).
Cheers!
I'm using symfony 4.2.3
`
parameters:
services:
`
Hey Roman R.
You are missing this piece of configuration:
So almost everything inside "src/" will be auto registered as a service. And because of that you don't need to define "api.form.login"
Cheers!
Thank you! That's works!!! But now my ide didnt know about Controllers methotds, I'm using php storm.
Have you installed Symfony plugin? And a couple others like Twig and annotations support?
Yes. I have its both and its enabled.
Hmm, try clearing the index. Go to settings -> symfony plugin -> clear index
It may do the trick :)
Already trying(((
And nothing? Sometimes by running "composer install" it get fixed. If not, try restarting PHPStorm... I'm running out of options =S
Hey Ryan it seems that the make:auth command has an upgrade now it give you 2 options
1: empty authenticator
2: login form authenticator
if you choose option 2 you get the name the security/autheticator
and your controller. will you update this later in the future when building and rendering forms?
Hey @Bobby!
Haha, like your name :). Yes, the new make:auth command awesomely now gives you the new option (2) - the login form authenticator. In this tutorial (before that option existed), we were effectively choosing option (1). And then we basically build (manually) a login form system. The final result of this tutorial actually looks quite similar to what you get if you choose option (2) (but we also wanted to build it manually so we could learn along the way).
Anyways, I'm not sure I've answered your question yet :).
> will you update this later in the future when building and rendering forms
In our forms tutorial, we will *not* do any more work on the login form system. Both in this tutorial and in the updated generator, it does not use the form system. There is nothing wrong with using the form system for the login form, it's just such a simple form (and its validation is a bit different) that I prefer just using HTML forms for it. The only thing you need to remember (which we do in this tutorial and the generator also does it) is to add CSRF protection to your form.
If I still haven't answered your question - let me know!
Cheers!
So if I understand correctly, when following the tutorial for learning purposes, we should choose "Empty authenticator" when running make:auth? Is there a simple instruction set to stay in line with the course at this point with the new wizard?
Thanks!
Nevermind. Should have just watched the video and seen the instructions added. Anyone else wondering -- just keep going.
haha, no worries Aaron, sometimes we all speak too fast :p
Hello,
After make the command make:auth, in the LoginFormAuthenticator class extends AbstractGuardAuthenticator and no AbstractAuthenticator. This is due to the update of Sf4? Why you don't use it ?
Hey Stephane!
Ah, typo! Yes, it should be AbstractGuardAuthenticator. It's not a Sf4 thing - it's just me saying the wrong class! You will see AbstractGuardAuthenticator in the video, even if I say something different in the script. Sorry for the confusion!
Cheers!
Hey Ryan,
Thank for your reply. But why you don't use AbstractGuardAuthenticator ? It's about simplicity ?
Hey Stephane!
Good question :). We change from AbstractGuardAuthenticator to AbstractFormLoginAuthenticator because, when you're building a login form, AbstractFormLoginAuthenticator requires you to do less work. If you look, AbstractFormLoginAuthenticator extends AbstractGuardAuthenticator, but it implements a few methods for you so that you don't have to. For example, when you're building a login form, we *know* that on failure, the user should be redirected to the login page. So, AbstractFormLoginAuthenticator implements the onAuthenticationError() method so that you don't have to.
In other words, AbstractFormLoginAuthenticator is just a "helper" sub-class that allows you to do less work when you're building a login form :).
Cheers!
"Houston: no signs of life"
Start the conversation!