Symfony Security: Beautiful Authentication, Powerful Authorization


What you'll be learning

Oh no, it's time to add security! Ahhh!

Wait, come back! Security in Symfony is awesome! Seriously, between things called "voters" and the Guard authentication system, you can do anything you want inside of Symfony, and the code to do it is simple and expressive.

Security has two sides: authentication (who are you?) and authorization (do you have access to do X). We'll talk about each of these, creating an traditional form login system and and API token authentication. Then, we'll turn to authorization, with roles, voters and other good stuff:

  • Making a User with the fancy new make:user command (ooOOOoo)
  • Security & Firewall Fundamentals
  • Creating a custom login form
  • CSRF protection
  • API token authentication system
  • All about Guard authentication
  • User Providers (why you need them, but don't care)
  • Password Encryption
  • Logging out!
  • Protecting entire URLs with access_control(s)
  • Checking access with roles! ROLE_USER
  • Denying access in a controller
  • What are voters?
  • Role hierarchies
  • Impersonation (switch_user)
  • Automatic Login (after Registration)

... and how to create a back door into your... spaceship... that will allow it to be destroyed with one careful shot. Just kidding! Let's make some secure sites / spaceships!

Your Guides

Ryan Weaver

Buy Access

Questions? Conversation?

  • 2020-03-09 Diego Aguiar

    Ohh, that's a problem indeed. The assets that your files depend on have to live in a public directory because they will be downloaded by the user's browser (unless you inline all the content in a single file). You may want to move all those assets to a public folder so they can be accessible

  • 2020-03-04 Lydie

    yep but it did not work due to the urls included in this html files (even if all the files were in the same directory).

    Ex: the. starting html file contains :

    <script src="story_content/user.js" type="text/javascript"></script>

    This can not be found as symfony will look into the public folder to find this file.

  • 2020-03-04 Diego Aguiar

    Have you tried to render it as you would do with any other template? I think it should just work if you render it with Twig, unless it contains PHP code inside it

  • 2020-03-04 Victor Bocharsky

    hey Wuwu,

    Look at Lulu tip here: - you don't want to extract that raw info from the session, better use "app" global Twig var that gives you access to the current user and other useful objects like request, etc.


  • 2020-03-04 Victor Bocharsky

    Hey Lulu,

    Thank for this tip!


  • 2020-03-04 lulu

    Dear wuwu,

    you can use twig global object User as {{ app.user.firstname }}

  • 2020-03-04 wuwu

    Inside Symfony profiler/Request/Response/Session/Attributes/_security_main we have this text format i.e.:
    ... \x00App\Entity\User\x00firstname";s:4:"John";s:25:"\x00 ...

    I'm trying to get the users firstname to display in twig when user is logged on. I wonder if I can get it from here ? Or i need to set it up manually in the session ?

  • 2020-03-04 Lydie

    render it :) it's an e-learning application done with html, javascript, css and video files.

  • 2020-03-03 Diego Aguiar

    Ah ok, I understand. It depends on what you want to do. Do you want to download the file, show it as plain text, or render it?

  • 2020-03-02 Lydie

    Thx Diego Aguiar .

    I have also thought about this solution but the issue for me is how to "redirect" to the entry point of the bundle? Most of my controllers render a twig template or return a JsonResponse for ajax request. How to return an html file?


  • 2020-03-02 Diego Aguiar

    Hey Lydie

    What you could do is to put all the bundle files in a non-accessible web directory (in other words, out of the public directory in Symfony), and then, code a controller's action (an endpoint), so it can check if there is a logged in user before serving any files. It's like a proxy, you first have to hit "some" route in order to access a file


  • 2020-03-01 Lydie


    I am not sure this is the right place to ask this question but as it's about secure access, I think this is not the worst place :) One of my customer sent me a bundle of files that should be accessed in a secure way (user must be at least logged in). This bundle is composed by html files (the starting point is an html files), javascript and css. All files must be placed in the same directory as they are links between them. This bundle has been generated by my customer with this tool: So I can not change the generated code (otherwise each time my customer will make a modification, I will have to redo my "adaptations". If I copy the files in a subfolder of the public folder, I can access them and it's working ... but it's completely open to everybody. Is there so a way in Symfony to "serve" html files in a protected way? Btw I am using Symfony 5.


  • 2019-11-06 CharlES

    I'm sorry for the delay, it was what I was planning to do, but I asked if there was any way less hard, but well you have already confirmed it to me, so I will do it that way. Thank so much

  • 2019-10-29 Diego Aguiar

    Ah I get it. What I've seen other sites doing is that they ping the server every minute (or maybe less) via javascript. So, they can know if the session already ended and if so, you execute your logic. Does it makes any sense to you?

  • 2019-10-29 CharlES

    Hey Diego Aguiar , when it has expired.

  • 2019-10-29 Diego Aguiar

    Hey CharlES

    So, you want to inform the user that his session has expired due to non-activity? Or what you mean by "When a session ends"?


  • 2019-10-28 CharlES

    Hello weaverryan ,
    I'm looking for SymfonyCasts the way to do it correctly when a session ends show a modal, either a login form or a few buttons to stay logged in or log out.
    Is there any of this or any thought of making a video?

  • 2019-10-22 khaled Sig

    thank you :)

  • 2019-10-22 Diego Aguiar

    Hey khaled Sig

    I recommend you to use this bundle


  • 2019-10-22 khaled Sig

    how can I login with facebook or google in Symfony?
    thank you

  • 2019-08-12 Victor Bocharsky

    Hey Hermes,

    I'm sorry to hear that it's too complex to you. Yes, I agree, API Platform / Messenger component might be a bit advanced for newcomers, but first of all it depends if you really need it or no. Well, I think we can answer the last question - you can just watch the whole tutorial and see if it's something you need or no. If no, it makes sense to skip it for you, you don't have to use ALL the Symfony components ;)

    > I understand you guys releasing one lesson a day, you have to keep your customers coming back. I also understand you have to cater to all kinds of programmers, beginners and advanced.

    Well, it's a bit more complex than you think. First of all, making a good video requires a big effort and consume time: you need to write code, record video and audio separately to make the video short without long pauses, add cool stuff like notices, annimation, etc to make it not so boring, upload it to a video hosting platform and release finally on our website. Most of the time we're trying to process one video per day while also working on other things like writing new tutorials, answering questions from our users, coding new features on SymfonyCasts, and fixing bugs :) So, we can release the entire tutorial at once, but for this our users would need to wait too long for this. Instead, we decided to deliver screencasts shortly video by video, so our users might start watching them even when we don't have all chapters recorded. We think it's the best strategy, we don't want our users to wait for about 1-2 months without no content and then release the entire tutorial at once. I hope you agree with us here.

    Also, fairly speaking, recently the first time in our practice when we're releasing a few tutorials simultaneously already the 2nd week in a row - it's API Platform and Messenger courses. Of course, we do really want to release a few tutorials at once, that's our main goal! And yes, it makes sense to release one beginner and one advanced course, but it depends on what courses we have completed for recording. This time it's these two.

    But more beginner courses soon - stay tuned!

    Thank you for your feedback! And thank you for your patience and understanding!


  • 2019-08-11 Hermen

    Hi Victor,

    I understand you guys releasing one lesson a day, you have to keep your customers coming back. I also understand you have to cater to all kinds of programmers, beginners and advanced.

    Truthfully, the latest tutorials are to advanced for me, at this moment. I don't even know why or when to use API-platform and/or Messenger so for the last two or three months I have lost interest in Symfonycasts. I am, however, eagerly awaiting the Translations tutorial.

    Perhaps you guys are willing to release a lesson from a beginner tutorial the one day and a lesson from an advanced (extracurricular) tutorial the other day? This would keep it interesting for both kind of users... And may I also suggest you start the beginners series with this Translations tutorial?

    Thanks anyway and keep up the great work!

  • 2019-05-16 Lydie

    Thx for your answer. I am indeed interested by the translatable behavior.

  • 2019-05-16 Victor Bocharsky

    Hey Lydie,

    Well, not really, because we're going to cover only translatable behavior from the KnpLabsDoctrineBehaviors bundles. And yes, this tutorial is on the finish stage, most probably we will start releasing it after API Platform course.

    Thank you for your patience!


  • 2019-05-15 Lydie

    Hi Victor!
    Did you get a chance to finalize the tutorial on KnpLabsDoctrineBehaviors ?

  • 2019-03-11 weaverryan

    Yo Skylar Scotlynn Gutman !

    Nothing exists like that currently - it's actually really cool idea though, however security rules are added in some many ways, it's hard to make a solution that would work for everyone. I *have* seen a company do this in the past who used security annotations for everything - they wrote their own console command. It's actually a bit easier than you may think, it involves:

    1) Iterating over all of your controller classes (I would probably use Finder to find all files in my Controller directory, then do a little string "playing" to convert that into class names)

    2) Inside the loop, use PHP Reflection ( to get all the methods.

    3) For each method, it it is public (if it's not public, just "continue"), use the annotations reader (autowireable by type-hinting the argument with Doctrine\Common\Annotations\Reader) and call getMethodAnnotations() to read the annotations off of that method. This will return all of the annotations, including @Route and @IsGranted. You can use this information to figure out which endpoints use which security config.

    This really requires very consistent use of annotations for security to work - if you have a bunch of security applied inside the function itself (e.g. $this->denyAccessUnlessGranted()</code),>

  • 2019-03-09 Skylar Scotlynn Gutman

    Is it possible to get security debug information that merges annotations and security.yaml? maybe a console command that show all controller actions and their associated rules? or maybe by endpoint?

  • 2019-03-07 Waldemar Dell

    Thank you very much. That's the answera I needed.Wow, I got an answer from Ryan, I feel so good. Love your Tutorials. I watched nearly everything about symfony 3.3. IT was great.

  • 2019-03-07 weaverryan

    Hey Waldemar Dell!

    Yes, in this tutorial, we do all authentication via Guard. The SimplePreAuthenticatorInterface was deprecate in Symfony 4.2 because it basically does the same thing as Guard, but Guard is a bit easier to use.


  • 2019-03-07 Waldemar Dell

    Hello. IS authentication Made via guard? Because there are Changes in SF 4.2. at SimplePreAuthenticatorInterface. Thanks in advance

  • 2019-03-04 weaverryan

    Hey Justin Voelker!

    Woohoo! Thanks for the update that it worked :).

    > I would like to try again, this time using AJAX to submit the login form. Basically, show the username/password, submit via AJAX, if the user needs 2FA pass back some JSON indicating the 2FA code is needed, show the 2FA field, submit the login again, this time with all three fields populated.

    Yes, except I would only submit the 2FA code the second time - not the *also* the email & password again. It's just not necessary (you can set something on the session that they have passed this first "step") and it *could* get weird because you'll need to keep the email & password fields somewhere on the DOM so you can re-submit those values. Basically, you CAN do what you're saying, just be aware that you will have the password "floating around" the client side a bit longer. But yea, you could use 1 or 2 authenticators really, no matter what you do. It's just a matter of code organization - so do what feels best.

    > Essentially, the only part I'm unsure about is how, if submitting a form via AJAX, are form/field errors handled

    By default, if you're extending the AbstractFormLoginAuthenticator, the onAuthenticationException method stores the validation error to the session and redirects you. I think you're already not relying on this, as you've overridden this method. So basically, you would just need to grab the exception error from the AuthenticationException and put it in the JSON you want to return - you can see what the base class does here: - what you actually need is $exception->getMessageKey() - that is the string that contains "what went wrong during authentication". Return that in the JSON, then it will be your responsibility to render that onto your form somehow via JavaScript.

    Let me know if that makes sense! Sounds like the feature will be awesome.


  • 2019-03-04 Victor Bocharsky

    Hey Hermen,

    To recap, you're interested in translation tutorial that covers StofDoctrineExtensionsBundle as far as I understand. And yeah, I have a great news for you! I'm working on this top secret translation tutorial right now, it should be released soon... I think we'll start releasing it in March! Though I'm going to cover KnpLabsDoctrineBehaviors instead of StofDoctrineExtensionsBundle just because if we're talking about Translatable behavior - it's implemented better by KnpLabs.


  • 2019-03-02 Hermen

    Sorry Victor, I was sure I had replied... I actually meant the Doctrine Extensions with the StofDoctrineExtensionsBundle. But it looks as if that project is revitalised...

    Any news about this tutorial, is it on the board?

  • 2019-02-28 Justin Voelker

    Awesome! It works perfectly! Quick note to anyone else trying this, the method is onAuthenticationFailure() not onAuthenticationException().

    Once I got this working (yay) I realized maybe I didn't fully think through the UX (boo). I would like to try again, this time using AJAX to submit the login form. Basically, show the username/password, submit via AJAX, if the user needs 2FA pass back some JSON indicating the 2FA code is needed, show the 2FA field, submit the login again, this time with all three fields populated. This would also be nicer as it only needs one authenticator. I'm guessing a POST request to the same path would work but I would need to somehow return JSON on failure.

    Essentially, the only part I'm unsure about is how, if submitting a form via AJAX, are form/field errors handled? Ideally I would keep the functionality of "wrong username or password" for the initial two fields, but then add some "wrong 2fa code" as necessary. Is there some JS form magic for working with forms/returned errors via AJAX?

    Thank you again for the incredible tutorials and assistance!

  • 2019-02-25 weaverryan

    Hey Justin!

    Actually, you nailed it - nice work! Ok, back story: Symfony doesn’t natively handle two factor auth. It’s not that it can’t - but no official solution has been set forward. I’ve never had to implement it, but I’ve been telling people for years to do exactly what you’re proposing. Let me see if I can fill in a few of the fuzzy pieces:

    1) in the first authenticator, once you determine that authentican is successful (you found their User), you cannot return the User from getUser(). That would cause auth to be successful, which is actually not what you want. You’ll need to create a custom Exception class and make it implement Synfony’s AuthenticationException. Add a User argument to the constructor, store the user on a property, and add a getUser() method to the exception class. Then, at the bottom of getUser(), instead of returning the user, throw now NowReadyForSecondStepAuthException($user) - or whatever you call it.

    2) this will cause onAuthenticationException() to be thrown. If you see a different exception, handle it like normal. But if you see this exception, store the user I’d in the session and redirect to whatever URL will hold your second step of auth.

    3) make your second authenticator only return true in supports() if the user is on the correct URL and if that session key exists. Do whatever you need to do here - it’s kind of a normal authenticator, except that it’s checking for and using that value in the session.

    4) and that’s it! You kinda don’t need to prevent the user from navigating away from the 2nd factor auth, because with this method, they are not authenticated at all until they complete step 2. If they navigate away, good for them - they are anonymous still.

    So, you can see that it’s kinda straightforward, but the details are tricky. There are people that definitely want to make this easier.

    Let’s me know what questions you have - happy to help!


  • 2019-02-25 Justin Voelker

    Hello and thank you for the incredible tutorials!

    Is there a way to implement a two-part authentication process? For example, after username and password are authenticated, some users would be logged in while others could be directed to a second login page to complete their login by providing, perhaps, a security question answer or two factor code?

    With very little Symfony experience so far I was hoping there was a "correct" way that I am just not aware of. My thought was to setup username/password authentication as described in this tutorial. Upon success, if logic determines another step is required, set a session variable. Then create another guard that looks for that session variable and prompt the user for the second part of the login process. I'm just not sure how to go about having this guard use a different page/form and how to restrict users from doing anything else on the site until that second part of the login is complete.

    Thanks again for the tutorials!

  • 2018-12-27 Diego Aguiar

    Hey Ovidiu Crihana

    Welcome to the Symfony world!

    1) First, you only need to define an entry point when you have more than one Guard Authenticator. In your case, I would prefer to have only one (open to public) login form and then protect the whole /admin/ URL namespace, so only admins can go to /admin/dashboard for example. If you really need two login forms, then you will have to create another Guard Authenticator, and then override the start() method to manage redirects properly. I recommend you to watch this chapter:

    2) This question is totally related to OOP and it's a big topic but in short, you would prefer to inject dependencies via the constructor when you want to use the same object's instance for all the time been of a dependent object, in other words, if you have a class (let's call it $a) that has a constructor argument of a MarkdownParser service, you know everytime that you use $a->render(), it will always use the same MarkdownParser instance.
    But, if instead the render method receives a MarkdownParser as an argument, then, everytime you call it, you (as a client) will have to provide a MarkdownParser instance, which can be a different instance and even a different type, in case that MarkdownParser is an Interface.

    3) Well, it depends on how complex or easy it is to use that library, usually I would create a service class that knows how to use the library, and just use it everywhere I need it.


  • 2018-12-27 Ovidiu Crihana

    Hello, I just finished this course and the previous ones about s4 and I wanted to ask a few questions if you would kindly reply. Coming from a non-framework background, I still struggle a bit wrapping my head around Symfony. So here are my questions:

    1. When we built the login form, we chose an entry point for where the form is located and how to respond on the submit. The problem is that you log normal users and admin with the same form. How would I go about building multiple login forms? I need a login form for the normal users(clients) and another one for the admins, basically the urls are /profile/login and /admin/login

    2. I am a bit confused about when I need to pass arguments in the __construct method of a class and when I don't need to. What I mean is, sometimes you just type hint an object in the method declaration and have it available, but other times you passed an object via the __construct method. Is there like a rule where I know what is available to me and what is not so that I need to inject it via the __construct ? Because I only worked with normal php, I always instantiate a class with new ClassName() and then inject it to other classes when needed.

    3. Finally, how would you recommend using third-parties libraries that have nothing to do with symfony? For example, I often use for image manipulation when I need to upload and resize images. How exactly would I use this library in my controller which handles the upload form, via __construct or there is a better way?

    Thank you again for these amazing courses and I apologize if my questions are too overwhelming.

  • 2018-11-26 Hermen

    So sorry, I meant Doctrine Extensions which, the last time I checked, was no longer maintained. It seems it is now maintained again...

    Looking forward to this update, working my way through the project now.

  • 2018-11-12 Victor Bocharsky

    Hey Hermen,

    What Symfony Extensions are you talking about? We'll base this screencast on our Stellar project that we're developing in every Symfony 4 screencast.


  • 2018-10-31 Hermen

    Hey Victor,

    Translations would be awesome, but... will you guys bring in the Symfony Extensions which are no longer maintained or will you start from scratch?

  • 2018-10-22 Victor Bocharsky

    Hey Vadim,

    We're sorry, it were weekends. Just answered both your emails. Thank you for your patience!


  • 2018-10-20 Nigel

    Hey, wrote a letter on your mail (through Contact Us section), still no answer (sir.****@y*.**)

  • 2018-10-18 weaverryan

    Hey Alex Bibiano González!

    Thank you! But... no - we don't :/. It's secretly on our TODO list to create a bundle that does ONLY this part, but it's not finished yet. And using FOSUserBundle just for the forgot password is overkill. I did find this gist today - - which contains some code (haven't tested it) for a manual reset password. It's really not *too* difficult (mostly a "chore") and that code clearly explains the steps needed. I hope it helps :).


  • 2018-10-17 Alex Bibiano González

    Very good course. Do you have plans to add a chapter about adding a “forgotten password” feature to this serie?

  • 2018-10-10 Victor Bocharsky

    Hey Nicholas,

    Thank you! Good luck with catching up ;)


  • 2018-10-10 Nicholas Njogu

    feels great catching up finally, Great casts Knp/

  • 2018-09-03 Victor Bocharsky

    Hey Jimmy,

    We completely released ReactJS tutorial finally, but now we have an intermediate small one - Contributing to Symfony: . So the next should be this one. Thank you for your patience!


  • 2018-09-02 Jimmy Silva

    Yes when will this one be completed?

  • 2018-08-08 Victor Bocharsky

    Hey Mike,

    We're going to release these 2 course next, but I can't guarantee we'll finish them in 2 months.. and it depends on do you need to finish your project in 2 months or you just need to create it in 2 months :) But yeah, we have plans to finish these 2 courses in 2 months I think.

    The other question is, do you want to use LTS version (that is 3.4) of Symfony for your project or do you want to use the newest 4.1? See this roadmap: . Probably starting project with LTS version is a good idea, and since it's 3.4 - you can totally follow those courses from Symfony 3 track. But please, use the Symfony Flex that supports Symfony 3.4 - it would be much easier to migrate to the Symfony 4 later. If you're about to use 4.1 - you can still follow those course from Symfony 3 track, you just need to do it in Symfony 4 way with Symfony Flex, the rest of the code is almost the same, but if you faced some problem following those tutorials on Symfony 4 - just ask your questions below videos and we'll try to help you.

    So, the original idea won't be changed too much for those new SF Auth & SF Forms, we'll just show how to do the same we did in Symfony 3 track but in Symfony 4 way usign Flex and some new features, so I don't think code will change too much.


  • 2018-08-07 Mike

    I need to create a new project within the next 2 months. I need SF Auth & SF Forms, do you recommend to use techniques from your old SF3 courses to handle this or should I use the new SF official docs for this? It would be great if i could code by example the SF auth system without rewriting the code when this course is out!

    Any suggestions?

  • 2018-08-01 Victor Bocharsky

    Hey Mike!

    Here's our upcoming tutorials list: - as you can see this one should be next for now. We need about 2-3 weeks to completely release ReactJS course, and, in the best case, I think this tutorial will be started releasing in a month. But that's just a wild guess for now, we'll have more precise dates after ReactJS. Thank you for your patience!


  • 2018-07-31 Mike

    I see that there are still react tutorial published, is there a new ETA? Cant wait to see this new high quality tutorial from you Ryan!

  • 2018-07-17 Victor Bocharsky

    Hey Knayz,

    We covered services and service container a lot in the new Symfony 4 Fundamentals: - check it out if you haven't seen it yet. More pro version of it would be have too, but we don't have any certain plans for it yet, so I don't tell you much about when it may be released. First of all, it will be Security, Forms, and probably Translations... what is the next - we will see :)


  • 2018-07-16 Knayz

    And what about Level up with services and the container?

  • 2018-07-16 Knayz

    Victor Bocharsky,
    thank you for the reply!

  • 2018-07-16 Victor Bocharsky

    Hey Knayz,

    Yes, we're moving this way as you can see, so the next are screencasts about Security and Forms.


  • 2018-07-14 Knayz

    Do you have plans to repeat all courses about SF3 for SF4?

  • 2018-07-09 weaverryan

    I agree! I'm finishing the React tutorial this week - then straight to security! Weeeee!!!!

  • 2018-07-09 kribo

    sounds good and is long over due... cannot wait to get started.

  • 2018-06-19 Felipe Martins

    I will be waiting for that.

  • 2018-06-19 mouerr

    will be a great tutorial, we are waiting :D

  • 2018-06-18 Victor Bocharsky

    Hey Arek,

    We're going to start releasing ReactJS tutorial this week, and then this one will be next I think. Thanks for your patience.

    You can track upcoming screencasts on this page:


  • 2018-06-16 Arek Mateusiak

    can't wait for this one :-) when it will be available? :-)