-
Notifications
You must be signed in to change notification settings - Fork 111
Dynamic role support #318
Comments
@Wilt thanks for your showing that up. We are planning the next major release of ZfcRbac that would bring middlewares concept, do you know it? As I said in #316, I'd like to allow developers to register their own "role provider" middleware, so that they could apply some custom logic for resolving the user roles: namespace UserLand\Middleware;
class MyCustomRoleProviderMiddleware
{
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
{
$roles = /* Custom logic to fetch identity roles */;
return $next($request->withAttribute('roles', $roles), $response);
}
} While I feel that this |
@danizord I am not familiar with the
In our application each resource has a known set of roles (Admin, Guest, Owner), we just need to collect the |
Should we invent a new authorisation system that is neither called Acl not Rbac and that does all this? So that we stop saying "this does not sound like Acl/Rbac" ? Ideally I'd love this library to be able to provide an authorisation as granular as what AWS provide for its IAM service. |
@bakura10 First I thought you were being sarcastic, but I sincerely hope you are serious. And yes, we should do that, I am in. And if necessary I would also not mind contributing to this.
|
I'm not sarcastic at all :). In my previous project I had this mechanism of "team" where one user could actually have different roles based on the sub-project he had created, so the same user could be potentially an admin, a super-user and a user at the same time, depending on the project. Therefore this is where AWS mechanism shines, where you can create permissions using simple logic, so you could have a permission for a given resource (so it looks a bit like a mix of RBAC and ACL) - this could actually be removed completely and only use "Condition" as shown after): {
"Effect": "allow",
"Permission": "read_article",
"Resource": "343" // An article ID
} Or going more deeper and creating conditions, based on context (and this context info would be exposed by the app, depending on the resource): {
"Effect": "allow",
"Permission": "read_article",
"Condition": {
"StringLike": {
"article.team.name": "team-bar-*"
}
}
} This user would have the permission to read the article only if the current context (the article) belongs to a team of writer whoes name starts by "team-bar-". You could also combine things and set a wildcard for "Permission": "*_article". @danizord what do you tihnk? |
Only my humble 5 cents about assertions etc. here, but... I think the proposed conditions above are really interesting idea. Similarly to Assertions. I certainly love the assertions and would not like to see it going away. As for it not belonging to the Rbac... well you might be right but this module (despite it's name) is to most people more than an Rbac. It's a module to solve most authorization needs. Background info (if interested): I have solved the issue by using (customized) zfcrbac and it’s assertion plugins (in some cases multiple ones). Having an assertion say visibilityAssertion that reads column ‘visibility’ of the context (feed post) and doing the check between the creator and viewer makes more sense. |
I definitely agree with the fact that assertions should not be gone. This is part of a very standard authorization system. As of today, the "AWS model" would work a bit like what you were doing. For instance, in AWS, whenever you create a new resource (for instance a new database...) and want to grant access for a user to this resource, you need to explicitly give the user the permission: {
"Effect": "allow",
"Permission": "read_db",
"Resource": "db-123b"
} So whenever you would create a new db, you would need to add a new policy rule for the user. Checking the "read_db" permission would therefore means retrieving all the given policies for this permission and user, and verify their validity. But as said before, AWS also uses a "condition" system that would allow to solve your issue with one rule. For instance, if the context for this permission would contain the provided data, you could grant a user a read access to all databases created after a given date: {
"Effect": "allow",
"Permission": "read_db",
"Resource": "*",
"Condition": [
"DateAfter": {
"db.created_at": "2015-01-01"
}
]
} And of course, you could mix everything, and give a user access to all db, created after a given date and before another date: {
"Effect": "allow",
"Permission": "read_db",
"Resource": "123-*",
"Condition": [
"DateAfter": {
"db.created_at": "2015-01-01"
},
"DateBefore": {
"db.created_at": "2016-01-01"
}
]
} Maybe such a module should enforce some convention. For instance in AWS a "Resource" always references what Amazon calls an ARN, which is like a identifier that allows to uniquely identify a resource. But that's definitely a big work, in the next few months I'll work on projects tht won't require advanced authorization so I'll likely won't work on that unfortunately :(. But feel free to submit other ideas! |
Thanks for the comprehensive answer. It makes sense. For now (v2) I will submit PR for multiple assertions in couple of days, and you see if you like it. |
I have a project where I customized Rbac. The thing was that I needed dynamic roles; a person can be an
Owner
/Admin
for one resource instance and for another resource instance of the same type (so a different resource identifier) he has for example no role at all (Guest
role). To be able to implement that I introduced aRoleResolver
.In my config I tie resource classes to certain role resolvers to be able to resolve the roles for the provided
$resource
instance for the currentAuthenticatedIdentity
at run time (or optional another identity passed to the resolver).something like:
My
RoleResolverInterface
looks like this:I created a
RoleResolverPluginManager
where I load the config. This allows easy access to the correct role resolver.In my authorization event I get the correct resource (or a resource reference) and resolve the roles for the current user for the resource so that the
isAuthorized
method in myAuthorizationService
can be executed with the correct roles for that particular resource.Would it be interesting to add such dynamic role support to this
RBAC
module? Or would it be interesting to make another module calledDynamicRBAC
? Or do you see other ways of achieving the same results with the current module?The text was updated successfully, but these errors were encountered: