Yii Framework Forum

Improving the RBAC to accommodate a wider range of popular use-cases


(Ptheofan) #1

One of the Apps I built has multiple company accounts. A user is bound to one or more accounts while can also be restricted to particular properties within the assigned accounts.

Adjusting RBAC to support multiple accounts was quite a lot of work whilst I had to modify some function signatures to accommodate for all the required changes.
Although It can be done in a fast and dirty way by formulating ids (like, “%s-%s-%s” and deconstructing on permission check level) but this hinders the queries performed in the db (quickly with a single query check if user is eligible). So I had to actually restructure a lot of stuff to add additional fields in the RBAC schema.

The problem in the existing RBAC is that almost all queries had to be reworked and additional functions introduced to handle the data loaded from the DB to properly populate the Objects.

It would be great if the RBAC in Yii3 is more extensible allowing us to easily accommodate additional data changes by simply extending the base classes. It would also be great if the functions performing RBAC checks supported by default structures (starting from User::can(…) all the way down to permissions).

By structures I mean

  • UserId is an Object (extending some base class will allow us to extend the data used to identify a user or resource in the system)
  • Permissions and etc. can be data-vectors (carry all kinds of additional custom data that might be needed accessible in a magic getter-setter or with concrete functions built in classes extending the base class)
  • Allow be default the use of Contexts that identify under which application contexts an RBAC item is valid (especially useful in GUI permissions assignment - think Admin, Frontend, Api, etc). Can be emulated similar to messages (translations) but it would be nicer to be cleaner and separate for improved db performance.

What do you think? Is it worth adding this type of extensibility in the RBAC system of Yii3?


#2

What you describe sounds a lot like it could be solved with using RBAC rules.

https://www.yiiframework.com/doc/guide/2.0/en/security-authorization#using-rules

Are you using rules in your setup?


(Ptheofan) #3

Rules cannot solve multi-account setups (and yes, I am using them extensively).

Imagine a platform that supports multiple accounts. Each user can be assigned to multiple accounts or none. To solve this you need to create complex ids in auth_assignment.
For instance “accountId-userId”. By doing that you add not only complexity to the queries but also a lot of additional computational cost not to mention you loose the data relational integrity guarantee of SQL.
This can be easily (in theory) solved by adding another column there, account_id.
To do that in the existing RBAC is quite painful as it’s tightly coupled in many parts of the code to the initial schema.

Then imagine you also need a “form” where roles hierarchies and rules can be edited and attached.
Bad luck again as there’s no clear indication in the db schema for contexts. Yes, you can have different sets of tables per context (admin, frontend, api, etc) but this just adds a lot of complexity which can be very easily be solved by adding another column called “context”.

So, what I ended up doing is extending the Auth manager, pretty much overloaded most functions to eliminate the tight schema coupling. I also modified the User::can function signature to accommodate the additional account_id information.

This is why I suggested using a more abstract approach when it comes to

  • Auth Manager and db schema

  • Objects to represent an a user id in RBAC.


#4

I am currently working on a system where a user can be assigned to multiple “accounts” with different roles in them. I am quite busy right now, but I might come back here and explain how I made that work with current Yii rbac later.


(Thyseus) #5

Hey @CeBe,

i am also interested in your solution, since we want to implement a kind of “multi-tenant” RBAC in the future, too. I would love to share the experiences we make here.


(Tom) #6

We do this in multiple projects of ours with Yii2 by extending the auth-assignment table with a foreign key column to point to the “object” the user is getting a role assigned to. For example:

In a system that has multiple stores, our auth assignment is not the default (item_name, user_id) but it is (item_name, user_id, store_id) because the user account of a store employee should get a role assigned not across the whole application, but only for one or more specific stores. The auth assignment only applies to the store with that ID. Consequence is that we generate an AuthAssignment model, controller & views and custom rule extensions (for can() statements), because we need to bypass a lot of the generic RBAC functionality.

Would be nice if RBAC supported this by default. Also, would be nice if auth_item would add an item_id INT primary key column and just make item_name unique. Strings are a lot more annoying to deal with when defining foreign key relationships in models as ActiveRecord and/or in joins.