Referencing non-parameter entries in config.yml - symfony

I have quite extensive config .yml files and I'd like to refer to various settings there:
security:
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_USER: ROLE_ADMIN
easy_admin:
entities:
Group:
form:
fields:
-
property: 'roles'
type: choice
type_options:
expanded: true
multiple: true
choices: "%security.role_hierarchy%"
Of course the last line doesn't work because %security.role_hierarchy% refers to parameters.security.role_hierarchy. Is there any valid way to reference security.role_hierarchy in easy_admin section?

The only valid way to do that in YAML is using the standard feature anchors and aliases. Anchors (that what is going to be referenced) are indicated by &<name> and alias (one or more points where the anchor is referenced) are indicated by '*`:
security:
role_hierarchy: &hr1
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_USER: ROLE_ADMIN
easy_admin:
entities:
Group:
form:
fields:
-
property: 'roles'
type: choice
type_options:
expanded: true
multiple: true
choices: *hr1
The value for the mapping entry choices, when retrieved will be the mapping:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_USER: ROLE_ADMIN
(translated to the hash or dictionary like object of the programming language the YAML parser is written in), and is the same entity as the value for the key role_hierarchy.

Related

Symfony4 Two authentification methods in security

I want two authentications methods in my application.
One for the entity User, and other (admin) with a plaintext.
Very simple.
Thus, when I configure security.yaml, I specify the providers:
security:
providers:
user:
entity:
class: App\Entity\User
property: username
in_memory:
memory:
users:
admin:
password: admin
roles: 'ROLE_ADMIN'
encoders:
App\Entity\User: bcrypt
Symfony\Component\Security\Core\User\User: plaintext
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin:
provider: in_memory
pattern: ^/admin/
guard:
provider: in_memory
form_login:
login_path: admin_login
check_path: admin_login
logout:
path: /admin/logout
target: /
default:
provider: user
anonymous: ~
guard:
provider: user
form_login:
login_path: login
check_path: login
default_target_path: login_redirect
use_referer: true
logout:
path: /logout
target: /
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/dashboard, roles: ROLE_USER }
And return the error:
In GuardAuthenticationFactory.php line 121:
Because you have multiple guard configurators, you need to set the "guard.e
ntry_point" key to one of your configurators ()
Then, if I have to set the guard.entry_point, I need do something like this:
admin:
entry_point: app.form_admin_authenticator
main:
entry_point: app.form_user_authenticator
And therefore, if I undestard, I need to configure a Authentication Listener like this: https://symfony.com/doc/current/components/security/authentication.html
(btw, this particular help page is very ambiguous and incomplete)
Is it necessary? It seems too complex for my purpose
I ran into this particular error. My situation might be a little different, but I had a similar need to authenticate using different authentication strategies depending on the entry point to the application.
One thing your config doesn't include is a reference to any Guard Authenticator objects. See this documentation for an intro to what role those objects play, and how to define them. Symfony's Security package is pretty complicated, and I found that using Guard Authenticators made the process a lot simpler for my use case.
Here is an example of a security.yaml config referencing two different authenticators. The entry_point configuration tells Symfony which one to try first, because in my particular case, Symfony otherwise wouldn't know which authentication strategy to apply first to an incoming request.
security:
providers:
user:
id: App\My\UserProviderClass
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
logout:
path: app_logout
guard:
entry_point: App\My\MainAuthenticator
authenticators:
- App\My\MainAuthenticator
- App\My\OtherAuthenticator
Custom Guard Authenticators contain a method called supports. This method takes the incoming request as its only argument, and returns true or false based on whether the given authenticator should be applied to the incoming request. A common practice might be to check the request's Symfony route name (as defined by the controller) or perhaps something like the full URI for the request. For example:
/**
* Does the authenticator support the given Request?
*
* If this returns false, the authenticator will be skipped.
*
* #param Request $request
*
* #return bool
*/
public function supports(Request $request): bool
{
$matchesMyRoute = 'some_route_name' ===
$request->attributes->get('_route');
$matchesMyUri = '/path/to/secured/resource' ===
$request->getUri();
return $matchesMyRoute || $matchesMyUri;
}
You can imagine that if multiple Guard Authenticators exist in the same application, it's likely the case that one would only want them to apply to a request of a certain type, whether the differentiation is based on the kind of auth applied (eg. a header with an API key vs. a stateful session cookie), whether the difference is more about the specific route being hit, or perhaps a combination of factors.
In this case, telling Symfony which Guard Authenticator to try first may be important for your security strategy, or may have performance ramifications. For example, if you had two authenticators, and one had to hit the database to verify a stateful session, but another could verify the request's authentication statelessly, eg. by verifying a JWT's signature, you'd probably want to make the JWT authenticator run first, because it might not need to make a round trip to the database to authenticate the request.
See this article for a deeper explanation: https://symfonycasts.com/screencast/symfony-security/entry-point

Symfony acl and role hierarchy in dashboard

I am pretty new to symfony and try to handle that framework.
Use symfony 2.8 with sonata admin 2.3 and user bundle 2.2.5
Got some interesting situation with ACL roles adding.
I have 2 roles in my project(user and admin) and needed to add one more(manager), but got stuck on situation with total ignore of any of that new role.
I am allowed to log in with the no problems but no dashboard is loaded to the admin_pool.
It's a part of my security.yml with allowed roles.
acl:
connection: default
providers:
fos_userbundle:
id: fos_user.user_manager
role_hierarchy:
ROLE_USER: [VIEW, LIST]
ROLE_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN]
ROLE_DIVISION_MANAGER: [OPERATOR, EXPORT, MASTER, OWNER]
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
and a part of my config.yml
where roles should be influence dashboard view.
dashboard:
blocks:
-
position: left
type: sonata.admin.block.admin_list
settings:
groups: [sonata_divison]
groups:
grower.management:
label: "Grower Management"
roles: [ADMIN]
sonata_user:
label: "Users"
roles: [ADMIN]
sonata_divison:
label: "Division Management"
roles: [ROLE_DIVISION_MANAGER, DIVISION_MANAGER]
items:
- admin.grower
- sonata.user.admin.user
security:
handler: sonata.admin.security.handler.acl
# acl security information
information:
OPERATOR: OPERATOR
EXPORT: EXPORT
LIST: LIST
VIEW: VIEW
USER: [VIEW, LIST]
DIVISION_MANAGER: [OPERATOR, EXPORT]
ADMIN: [MASTER, OWNER]
Are there any thoughts why dashboard is blank for division manager?

Symfony YAML include file

How can I split my security.yml into multiple files?
I know about the imports statement, but I need to import the role_hierarchy.
For example
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_USER:
//IMPORT FROM USER.YML
ROLE_SELLER:
//IMPORT FROM ANOTHER SELLER.YML
ROLE_ADMIN:
//IMPORT FROM ADMIN.YML
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
I need this because I want to define the roles for sonata admin's, and I don't want to store them in the database.
Thank you.
You could create the roles as config parameters:
// user_roles.yml
parameters:
seller_roles: [ROLE_A, ROLE_B, ROLE_C]
And use them in the security config:
// security.yml
imports:
- { resource: user_roles.yml }
security:
role_hierarchy:
ROLE_SELLER: %seller_roles%

Symfony user Role inheritance

I am currently working on a system using symfony (with FOSUserBundle), and i have multiple roles within the role_hierarchy, which i would like to utilize inheritance.
I have the role_hierarchy of:
role_hierarchy:
ROLE_MEMBER: ROLE_USER
ROLE_MONITOR: ROLE_MEMBER
ROLE_SUPERVISOR: ROLE_MONITOR
ROLE_MANAGER: ROLE_SUPERVISOR
ROLE_ADMIN: ROLE_MEMBER
ROLE_SUPER_ADMIN: [ROLE_MANAGER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
If the user i am logged in as has ROLE_SUPERVISOR and i call:
$this->get('security.context')->isGranted('ROLE_MONITOR')
I would expect this to return true, but it currently returns false.
Without adding every role to each user, is it possible to inherit roles so that if i called isGranted, it would check all other "related roles" within the hierarchy? and if so, how?
You need to put [] around your roles. This works as expected for me:
role_hierarchy:
ROLE_USER: []
ROLE_STAFF: [ROLE_USER]
ROLE_SCORE_ENTRY: [ROLE_USER, ROLE_STAFF]
ROLE_SCORE_ADMIN: [ROLE_USER, ROLE_STAFF, ROLE_SCORE_ENTRY]
ROLE_ASSIGNOR: [ROLE_STAFF]
ROLE_ASSIGNOR_KAC: [ROLE_ASSIGNOR]
ROLE_ASSIGNOR_CORE: [ROLE_ASSIGNOR]
ROLE_ASSIGNOR_EXTRA: [ROLE_ASSIGNOR]
ROLE_ASSIGNOR_ADMIN:
- ROLE_ASSIGNOR
- ROLE_ASSIGNOR_KAC
- ROLE_ASSIGNOR_CORE
- ROLE_ASSIGNOR_EXTRA
ROLE_DEVELOPER: [ROLE_USER]
ROLE_ADMIN:
- ROLE_STAFF
- ROLE_ASSIGNOR_ADMIN
- ROLE_SCORE_ADMIN
- ROLE_ALLOWED_TO_SWITCH
ROLE_SUPER_ADMIN:
- ROLE_ADMIN
- ROLE_DEVELOPER
- ROLE_ALLOWED_TO_SWITCH

How can delete default block of SonataUserBundle or SonataMediaBundle in SonataAdminbundle list?

I do not know how can delete the default block of UserBundle, MediaBundle (just one of them...).
This is my config.yml:
dashboard:
blocks:
# display a dashboard block
- { position: left, type: sonata.admin.block.admin_list }
# groups:
# sonata_page:
# label: Taules
# items:
# - sonata.admin.collection
# - sonata.admin.gender
# - sonata.admin.family
# - sonata.admin.color
# - sonata.admin.size
# - sonata.admin.article
And my security.yml:
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_SONATA_READER:
- ROLE_SONATA_ADMIN_LIST
- ROLE_SONATA_ADMIN_VIEW
ROLE_SONATA_EDITOR:
- ROLE_SONATA_ADMIN_CREATE
- ROLE_SONATA_ADMIN_EDIT
ROLE_SONATA_ADMIN:
- ROLE_SONATA_ADMIN_DELETE
- ROLE_SONATA_ADMIN_EXPORT
ROLE_STAFF: [ROLE_USER, ROLE_SONATA_READER]
ROLE_ADMIN: [ROLE_STAFF ,ROLE_SONATA_EDITOR, ROLE_SONATA_ADMIN]
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
You can use the Sonata AdminBundle security option to use the Role Handler, to let only one group the access to these administrations.
sonata_admin:
security:
handler: sonata.admin.security.handler.role

Resources