Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
NotificationsYou must be signed in to change notification settings

sandstorm/NeosAcl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This package implements dynamic Access Control Lists for Neos Roles.

The development of this package was sponsored byujamii andqueo.

Main features:

  • SwitchRestrictedEditor to an allowlist-only permission approach. By installing this package, theRestrictedEditor isno longer allowed to change any content.
  • Configure dynamic roles through a Neos backend module.
  • Permissions on the node tree, workspaces and dimensions possible.
  • Permissions work predictably with sane defaults and purely additive logic.

listing

edit

Installation

  1. Install the package:
composer require sandstorm/neosacl
  1. Run the migrations
./flow doctrine:migrate
  1. Log in with an admin account and visit the new menu entry 'Dynamic Roles'

Development

Initial (Package) Setup

  • Clone this package asSandstorm.NeosAcl in the DistributionPackages of a Neos 4.3 or later installation
  • Add it tocomposer.json as"sandstorm/neosacl": "*"
  • Runcomposer update

Initial React Setup

cd Resources/Private/react-acl-editoryarnyarn dev

Then, log into the backend of Neos, and visit the module "Dynamic Roles".

Internal Implementation Details

Implementing Dynamic Node Privileges and MethodPrivileges

The basic idea was the following: Hook intoPolicyService::emitConfigurationLoaded, and modify the$configuration array (introduce new rolesand privilegeTargets). This basically worksat runtime - however there is a problem with dynamic MethodPrivilege enforcement, which isexplained below and by the following diagram:

Concept

How do Method Privileges work

  • Background: An implementation ofPointcutFilterInterface can - during compile time of Flow - decide which classesand methods match for a certain aspect.
    • This is used inPolicyEnforcementAspect (which is the central point for enforcingMethodPrivileges).
    • There, theMethodPrivilegePointcutFilter is referenced.
    • TheMethodPrivilegePointcutFilter asks thePolicyService for all configuredMethodPrivileges - and ensuresAOP proxies are built for these methods.
  • Side Effect: Now, during building up the pointcut filters, theMethodPrivilegePointcutFilteradditionally builds upa data structuremethodPermissions - which remembers whichMethodPrivileges are registered for which method.
    • This data structure is storedpersistently in theFlow_Security_Authorization_Privilege_Method cache.
    • At runtime, for a class which is intercepted byPolicyEnforcementAspect, all configuredMethodPrivileges areinvoked - and they have to quickly decide if they matchthis particular call-site.
    • This is done using themethodPermissions data structure from theFlow_Security_Authorization_Privilege_Method cache.

What's the problem with dynamically added MethodPrivileges

  • If aMethodPrivilege is defined dynamically at runtime, then themethodPermissions data structure is missingthe information that this new privilege should be invoked for certain methods.
  • NOTE: You can only dynamically addMethodPrivileges for call-siteswhich are already instrumented by AOP;because otherwise the code will never get invoked (because of missing proxies).

We are mostly working withEditNodePrivilege etc. - so why does this apply there?

  • EditNodePrivilege has an internalMethodPrivilegewhich takes care of the method call enforcement part;i.e. preventing you to call e.g.NodeInterface::setProperty() if you do not have the permission to do so.

Furthermore, to make this idea work, thePolicy.yaml of this package defines a catch-allSandstorm.NeosAcl:EditAllNodesPrivilegeTarget - so AOP will instrument the corresponding methods ofNodeInterface. This catch-all makes sensein any case, because this switches the security frameworkto an allowlist-only approach

  • making it easier to grasp.

The goal

In order to make the dynamic policy enforcement work, we need to add custom stuff to themethodPermissions - forthe dynamically added roles.

Implementation

The post-processing of themethodPermissions is done using a custom cache frontend (SecurityAuthorizationPrivilegeMethodCacheFrontend).

Implementing dynamic AOP Runtime Expressions

Method privileges internally can use dynamic AOP Runtime Expressions (in case you check for method parameters). EspeciallytheMethodPrivilege - which is attached to theRemoveNodePrivilege - uses the following expression code:

return'within(' . NodeInterface::class .') && method(.*->setRemoved(removed == true))';

Theremoved == true part is a so-calledAOP Runtime Expression.

This is internally implemented using theFlow_Aop_RuntimeExpressions "cache", which is pre-filled again during the compiletime (which is a nasty side-effect).

Thus, in our case we need to again implement a custom cache frontend (AopRuntimeExpressionsCacheFrontend),using the runtime expressions of the base configuration, which exists properly.


[8]ページ先頭

©2009-2025 Movatter.jp