Multiple firewalls improve security in Symfony 5.4
P粉952365143
2023-08-26 16:14:30
<p>I'm trying to separate the user's authentication from the admin's authentication. </p>
<p>So I created 2 firewalls and 2 different access controls. </p>
<p>My security.yaml file is as follows:</p>
<pre class="brush:php;toolbar:false;">enable_authenticator_manager: true
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
providers:
owner_authentication:
entity:
class: App\Entity\Merchant\Owner
property: emailAddress
user_authentication:
entity:
class: App\Entity\User\User
property: emailAddress
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
user:
lazy: true
pattern: ^/admin/login/
provider: user_authentication
user_checker: App\Security\AuthenticableModelChecker
form_login:
provider: user_authentication
default_target_path: app.dashboard.index
use_referer: true
use_forward: false
login_path: app.authorization.admin_login
check_path: app.authorization.admin_login
username_parameter: login[emailAddress]
password_parameter: login[password]
logout:
path: app.authorization.logout
target: app.authorization.admin_login
main:
lazy: true
pattern: ^/
provider: owner_authentication
user_checker: App\Security\AuthenticableModelChecker
form_login:
provider: owner_authentication
default_target_path: app.dashboard.index
use_referer: true
use_forward: false
login_path: app.authorization.login
check_path: app.authorization.login
username_parameter: login[emailAddress]
password_parameter: login[password]
logout:
path: app.authorization.logout
target: app.authorization.login
access_control:
- { path: ^/admin/login, roles: PUBLIC_ACCESS}
- { path: ^/login, roles: PUBLIC_ACCESS }
- { path: ^/, roles: ROLE_USER }</pre>
<p>Everything works fine on the main firewall, but when I use the user (admin) firewall submit button, the login page refreshes itself and then nothing happens. I don't get any errors. </p>
<p>** If I add a user (admin) login on the main firewall, then /admin/login works fine and the other one no longer works. </p>
<p>When I call <code>$authenticationUtils->getLastAuthenticationError()</code>, I don't get any errors. But validation doesn't work either.</p>
<p>This is what my controller looks like: </p>
<pre class="brush:php;toolbar:false;">public function adminLogin(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('app.dashboard.index');
}
$loginForm = $this->createForm(LoginType::class, ['emailAddress' => $authenticationUtils->getLastUsername()]);
return $this->renderForm('app/pages/authorization/admin_login.html.twig', [
'title' => 'Log in',
'login_form' => $loginForm,
'error' => $authenticationUtils->getLastAuthenticationError()?->getMessageKey(),
]);
}</pre>
<p>This is the same problem a person had: https://grafikart.fr/forum/35234, but I couldn't find any solution. </p>
Finally, I found the answer and I will post it here: https://stackoverflow.com/a/42352112/8003007 All I need to do is add a
context: my_context
in both firewalls.This is a hard-to-identify option because it does not appear in the official and current Symfony documentation, but only in previous versions, such as Symfony 3.4.