Files
Symfony's Security Bundle comes well packaged, and for our use cases, there currently aren't
that many files that need to be looked at !
Configuring the bundle is indeed almost all we need to do !
security.yaml
Let's take a look at this bundle's configuration file, called security.yaml
.
You can find it located at config/packages/security.yaml
and it looks like that :
security:
enable_authenticator_manager: true
password_hashers:
App\Entity\User: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
providers:
doctrine:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
access_denied_handler: App\Security\AccessDeniedHandler
pattern: ^/
form_login:
login_path: login
check_path: login_check
always_use_default_target_path: true
default_target_path: /
logout: ~
access_control:
- { path: ^/login, roles: PUBLIC_ACCESS }
- { path: ^/users, roles: ROLE_ADMIN }
- { path: ^/, roles: ROLE_USER }
Let us break some of these configuration options down:
password_hashers
It corresponds to the type of algorithm that will be used to hash the passwords of our users
providers
Here we are telling our app that the security will be defined around our App\Entity\User
class,
and that doctrine, our ORM, will be in charge to load (when logging in for instance) our User from the
database, using its username
as identifier.
firewalls
The firewalls will define which part of our application are secured and how Users will be required to
authenticate.
Only one firewall will be working for each request, depending on how we have defined its
pattern:
Here, for instance, the dev
firewall will just make sure we do not block routes generated by Symfony
dev tools, like the profiler, and that anyone in
development will be able to access them (These routes will not exist in a production env).
The main
firewall will take care of all others incoming requests in this case.
Note: |
---|
As mentioned in the Documentation:
Visiting a URL under a firewall doesn't necessarily require you to be authenticated (e.g. the login form has to be accessible or some parts of your application are public).
So it does not mean that every route will be blocked ! We will learn a bit more about it when differentiating between Authorization and Authentication
I intentionally left the role_hierarchy
and access_control
out, they will be further explained
in the next section !
AccessDeniedHandler
You may have seen in the security.yaml part that we defined a custom access denied handler:
main:
access_denied_handler: App\Security\AccessDeniedHandler
If you take a look at the class, (located in src/Security
) you will see:
class AccessDeniedHandler implements AccessDeniedHandlerInterface
{
public function __construct(private readonly UrlGeneratorInterface $router)
{
}
/**
* {@inheritDoc}
*/
public function handle(Request $request, AccessDeniedException $accessDeniedException): ?Response
{
return new RedirectResponse($this->router->generate('index'));
}
}
This class will be responsible to intercept any AccessDenied Response sent by the firewall to the app user and redirect them to the homepage instead of generating a 403 page (which can be confusing)