Reputation: 9552
I setup my security settings to protect everything which is under the root path /
, exept for a public page to view the privacy policy, /privacy
. Everything works fine.
# security.yml
access_control:
- { path: ^/privacy$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, role: ROLE_USER }
Now I added some different translations to the privacy policy page, so that the route changes from /privacy
to /{_locale}/privacy
. Unfortunately I cannot add the _locale
parameter to the security path like this:
access_control:
...
- { path: ^/{_locale}/privacy$, role: IS_AUTHENTICATED_ANONYMOUSLY }
So how do I have to modify my security.yml
so that I can add the _locale
to the path and to restrict it to predefined languages, e.g. (en|fr|es|de)
?
Upvotes: 11
Views: 8203
Reputation: 22480
Nowadays (since Symfony 4.1 or later) you can define the locales in one place and use it everywhere in your application
in config/services.yaml
add
parameters:
myAppName.locales: en|fr|es|de
in config/routes.yaml
cms:
prefix: /{_locale}/
controller: App\Controller\DefaultController::index
requirements:
_locale: '%myAppName.locales%'
in config/packages/security.yaml
security:
## .... no changes here
access_control:
- { path: ^/(%myAppName.locales%)/cms, roles: ROLE_ADMIN }
Upvotes: 10
Reputation: 52493
If all your locales are 2-character ones (en|fr|es|de|...
) you can use a more generic regex like this:
- { path: '^/[a-z]{2}/privacy$', role: 'IS_AUTHENTICATED_ANONYMOUSLY' }
This way you won't have to touch your security.access_control
every time you add a new locale.
For locales in the form EN_en
you could use something like this btw:
- { path: '^/[a-zA-Z]{2}_[a-zA-Z]{2}/privacy$', role: 'IS_AUTHENTICATED_ANONYMOUSLY' }
Upvotes: 9
Reputation: 1409
I have the same issue and I resolve it by making some changes to the pattern in my secure area in firewalls setting. And then updating the access controls. The code is below
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin_area:
context: admin_area
anonymous: ~
pattern: ^/(en|ar)/admin/*
form_login:
login_path: admin_login
check_path: admin_login
default_target_path: admin_home
provider: admins
logout:
path: admin_logout
target: admin_login
below is the access_controll
access_control:
- { path: ^/(en|ar)/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/(en|ar)/admin, roles: ROLE_ADMIN }
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
Upvotes: 1
Reputation: 9552
I managed to solve the problem like this
access_control:
...
- { path: ^/(en|fr|es|de)/privacy$, role: IS_AUTHENTICATED_ANONYMOUSLY }
A recommendation for other answerers: I now have to enter this string (en|fr|de)
into all routes manually. When I add a language I have to modifiy this string in many occurences. It would be much better if one could define a string
parameters:
languages: "(en|fr|es|de)"
And use this in the route
- { path: ^/%languages%/privacy$, role: IS_AUTHENTICATED_ANONYMOUSLY }
But I don't think this will work.
Upvotes: 8