Define roles in a bundle config - symfony

I have some questions about roles that I'm trying to understand a long time:
1. We have some bundles that we use in couple of projects. We would like to define roles in a bundle config, so that we do not copy roles into the role_hierarchy in security.yml. Is there any clean way to do it?
My first idea was to import them into role_hierarchy like this:
role_hierarchy:
ROLE_ADMIN: ROLE_USER, ROLE_TRANSLATOR
ROLE_SUPER_ADMIN: ROLE_ADMIN
ROLE_NOT_APPROVED_USER: ROLE_USER
ROLE_TRANSLATOR: ROLE_USER
"%base_bundle.role.hierarchy%"
This of course doesn't work. Is there any possibility to do it this way(merge arrays in yaml)?
My other idea was to store roles in DB, but in my opinion it's overkill, because we have no dynamic roles. Everything is static.
Is there any workaround to achieve what I try to do? Or is it a good idea to define it in a bundle?
2. I use roles as permissions (ROLE_POST_EDIT, ROLE_POST_DELETE, ...) and voters to deny or approve access to the resource. So at the end there are a tons of roles. Is it a good idea to mix roles with permissions? If not what is the best practise?
EDIT: I feel the difference between ROLE_POST_EDIT and ROLE_USER or ROLE_ADMIN. User has ROLE_USER because he is user. But user has "permission ROLE_EDIT_POST" to be able to edit a post. In my opinion there is a difference between. Anyway should I care about this difference or is there any other practise how to do?

We have some bundles that we use in couple of projects. We would like to define roles in a bundle config, so that we do not copy roles into the role_hierarchy in security.yml. Is there any clean way to do it?
You can use Prepended Extensions to "prepend" configuration of another extension:
class AcmeHelloExtension extends Extension implements PrependExtensionInterface
{
// ...
public function prepend(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', [
'role_hierarchy' => [
'ROLE_ADMIN' => ...
...
],
]);
}
}
I use roles as permissions (ROLE_POST_EDIT, ROLE_POST_DELETE, ...) and voters to deny or approve access to the resource. So at the end there are a tons of roles. Is it a good idea to mix roles with permissions? If not what is the best practise?
A small misconfusion here: The roles you define with role_hierarchy are not related to the things you pass to isGranted(). You're passing attributes to isGranted(). Unfortunately, for the RoleHierarchyVoter, symfony decided to make the attributes similair to the role name (that is, if the role name starts with ROLE_).
Voters vote on permissions, or attributes as they are called. So it's perfectly valid and good practice to have many permissions in isGranted().
However, I recommend not to start them with ROLE_*. These attributes are checked by the RoleVoter/RoleHierarchyVoter. Name them e.g. POST_EDIT, POST_DELETE:
if ($this->isGranted('POST_EDIT', $post)) {
// ...
}

Related

How to authorize custom user from db in Symfony4

I just need to authorize custom user. Without any froms, tokens and etc. I have user entity in my DB.
User class is already configuren it fos_user.yaml:
fos_user:
db_driver: orm
firewall_name: main
from_email:
address: '***#*******.**'
sender_name: '**.****.**'
user_class: App\Entity\User
Is it possible? Somethong like
Authurizer::authorize($userEntity)
Thanks.
Authorization in Symfony done Tokens. To be logged in Symfony's World you'll need to set a Token.
One of the common use cases is "auto login" right after registration.
Take a look at this article -> https://ourcodeworld.com/articles/read/459/how-to-authenticate-login-manually-an-user-in-a-controller-with-or-without-fosuserbundle-on-symfony-3
especially for that part
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
BUT also take a look at symfony's impersonalizaiton => https://symfony.com/doc/current/security/impersonating_user.html
It basically allows you to switch users without filling out forms and knowing users' credentials
Custom Commands for FOSUserBundle are
fos:user:activate
fos:user:change-password
fos:user:create
fos:user:deactivate
fos:user:demote
fos:user:promote
There is no such way to authorize directly as you want it.
You can create a custom command in symfony which accepts username and authenticates a user. Here is a way to create such a command : https://symfony.com/doc/current/console.html
Thanks you, guys! I found the solution here!
How to programmatically login/authenticate a user?
Sorry for wrong or stupid question.

Symfony2 User permission managment

I come to you because I have a little concern about the management of users and their Permissions with Symfony2.
Let me explain:
I set up the FOSUserBundle:
What I'd like to do now is a rights management. I have an entity 'Post'.
I have users with roles specified below.
ROLE_GUEST - VIEW,RATE
ROLE_USER - VIEW,CREATE,RATE,EDIT_OWN
ROLE_EDITOR - VIEW,CREATE,RATE,EDIT,DELETE
I want to set permission to each roles for performing certain actions.
Thank you :)
If i understand your necessity correctly you want to have a security layer based on those roles. You can do this in may ways:
The symfony default way -
you can configure the security layer of symfony like in the example below
# app/config/security.yml
security:
# ...
access_control:
- { path: ^/post/view, roles: VIEW }
- { path: ^/post/rate, roles: RATE }
# etc
This will take care of route access control. More info on http://symfony.com/doc/current/cookbook/security/access_control.html
For more complex roles like EDIT_OWN, you can take the direct approach
if (!$post->isAuthor($this->getUser())) {
$this->denyAccessUnlessGranted('EDIT', $post);
// or without the shortcut:
//
// use Symfony\Component\Security\Core\Exception\AccessDeniedException;
// ...
//
// if (!$this->get('security.authorization_checker')->isGranted('edit', $post)) {
// throw $this->createAccessDeniedException();
// }
} else {
$this->denyAccessUnlessGranted('EDIT_OWN', $post);
}
For all this and more you can check the symfony site http://symfony.com/doc/current/best_practices/security.html
For even more advanced roles or ACL requirement also take a look here https://symfony.com/doc/current/components/security/authorization.html and at the authorization voters https://symfony.com/doc/current/components/security/authorization.html#voters
In the 4 links I provided in this post you should find all you need to implement RBAC as well as ACL. You can also find information about some annotations you may want to use. Also there are some extensions to the symfony security layer that may come in handy depending on the symfony version you are working on like JMS\SecurityExtraBundle.
Hope this help,
Alexandru Cosoi

Symfony 2.8+ LDAP Roles

I have set up the new LDAP system with symfony 2.8+
LDAP but I have a problem with the role. It is stated in the documentation that
# app/config/security.yml
security:
# ...
providers:
app_users:
ldap:
service: app.ldap
base_dn: dc=example,dc=com
search_dn: CN=My User,OU=Users,DC=example,DC=com
search_password: p455w0rd
filter: (sAMAccountName={username})
**default_roles: ROLE_USER**
But I don't know, how it works. I would like to get the user from my LDAP and then give them roles. Is it possible with the new LDAP Sytem within symfony ?
I previously used IMAG/LdapBundle but you can't set your own roles because of a bug never patched which prevent modifications from beiing saved...
It currently is not really possible in the Symfony LDAP component (as of the most current, 3.1). See this open issue.
However, I maintain a bundle that allows this as you can define roles that map to specific LDAP groups: https://github.com/ldaptools/ldaptools-bundle. Dunno if that will help you, but I tried to give it a lot of different configuration options.

Change role of one user no working with Symfony2

Sorry if this question has been asked many times but I didn't found any solution on the Web.
So, I just have installed FOSUserBundle and I've created 2 users on my application with the console. The problem is they don't have any role.
So in on controller, I get the user Entity and y set his role but when I try to access to a page restricted for admin, it says access denied. Moreover, the roles has no changed on the databse.
My code in the controller :
$user = $this->container->get('security.context')->getToken()->getUser();
$user->setRoles('ROLE_ADMIN');
if (!$this->get('security.context')->isGranted('ROLE_ADMIN')){
throw new AccessDniedException('Access Denied !');
}
Anyone have an idea ?
Thanks in advance !
It is a very bad practice to set a user role in your controller if you want to keep them away from the controller in the first place. I hope you use this line of code for testing only.
The FOSUserBundle provides a number of command line utilities to help manage your application's users.
The one you need is:
$ php app/console fos:user:promote testuser ROLE_ADMIN
Replace testuser with your username.
Did you also define your roles in your firewall?

Using dynamic roles in security.yml

I have a Ldap repository storing roles for users. They are already mapped to Symfony roles.
I would like to use them in the security.yml but I cannot hard code role values because they evolve with the application.
Is it possible to have something like this?
access_control:
- { path: ^/project/$project, roles: ROLE_$project_MEMBER }
Thanks.
Have you taken a look at implementing ACL? See also this piece of documentation.
i'm also stuck in the same problem you have to give roles which is stored in your in DB like
access_control:
- { path: ^/Services/, role: ROLE_USER }
there is no way and it's not good to do it the way I wanted, I've ended using the voters system using affirmative strategy

Resources