Thanks, Brian! There you go, Richard, you can comment / upvote that one.
> On Jul 7, 2016, at 8:18 AM, Brian Demers <[email protected]> wrote: > > Take a look at this one: https://issues.apache.org/jira/browse/SHIRO-314 > <https://issues.apache.org/jira/browse/SHIRO-314> > > > On Thu, Jul 7, 2016 at 4:46 AM, Lenny Primak <[email protected] > <mailto:[email protected]>> wrote: > Ok, you can open an enhancement JIRA with that. > > > On Jul 7, 2016, at 3:43 AM, Richard Adams <[email protected] > > <mailto:[email protected]>> wrote: > > > > Well, Spring Security implements ACL; > > http://docs.spring.io/spring-security/site/docs/3.0.x/reference/domain-acls.html > > > > <http://docs.spring.io/spring-security/site/docs/3.0.x/reference/domain-acls.html> > >> On 7 Jul 2016, at 09:42, Lenny Primak <[email protected] > >> <mailto:[email protected]>> wrote: > >> > >> The tricky thing is to figure out what the common feature set actually is > >> (i.e. to design it or take already existing design) > >> Is there another framework that you know of or any existing project that > >> implements this already? > >> If this was such a desirable feature for lots of people, it would be hard > >> to believe that this wasn’t already implemented somewhere. > >> > >>> On Jul 7, 2016, at 3:39 AM, Richard Adams <[email protected] > >>> <mailto:[email protected]>> wrote: > >>> > >>> Yes, I take your point - Shiro has all the Core features you need to get > >>> started, it’s conciseness is one of its main attractions, and there’s > >>> certainly a strong argument to avoid feature bloat and unnecessary > >>> complexity. > >>> But, perhaps it is the case, that if many Shiro users are independently > >>> having to extend Shiro to obtain additional similar functionality, then > >>> there is a case for considering adding to Shiro. > >>> Richard > >>>> On 7 Jul 2016, at 09:26, Lenny Primak <[email protected] > >>>> <mailto:[email protected]>> wrote: > >>>> > >>>> My sentiments exactly. > >>>> > >>>> There are a lot of SNACs (shiny new ACronyms) popping up every few > >>>> months that “some other framework” may have that are “missing” from > >>>> Shiro, > >>>> like many variants of **BAC (which are very much too vaguely defined, > >>>> and not in any way standard) > >>>> All of this can easily be solved by a few lines of custom code (in > >>>> custom realm etc.) > >>>> You can’t possibly chase all those vague acronyms and succeed. > >>>> > >>>> Saying that, I am not opposed to adding some sort of additional > >>>> abstraction layer for **BAC, but it has to be well defined. > >>>> > >>>> Here is what I see as viable options: > >>>> - Write an implementation yourself on top of Shiro, get traction in the > >>>> wild, and then contribute it to Shiro, if still makes sense. > >>>> - Point out specific code / features / documentation in another > >>>> framework that implements your feature that has traction in the industry, > >>>> i.e. has proven useful in the wild, and propose inclusion of such > >>>> specific functionality in Shiro. > >>>> > >>>>> On Jul 7, 2016, at 3:02 AM, Richard Bradley > >>>>> <[email protected] <mailto:[email protected]>> > >>>>> wrote: > >>>>> > >>>>> Could you explain what the benefit of this is over just implementing > >>>>> those restrictions in plain old Java code directly? > >>>>> > >>>>> Each of the use cases you have given could be translated into plain old > >>>>> Java code more or less 1-1 and the resulting code would be: > >>>>> 1. simpler > >>>>> 2. more maintainable > >>>>> 3. more accessible to newcomers (no new language needs to be learnt) > >>>>> 4. benefit from IDE support and static analysis support > >>>>> 5. likely more reliable (there are fewer moving parts; no AOP framework > >>>>> is needed etc.; no chance of bugs in the implementation of > >>>>> @RequiresAttributes or misunderstandings in its usage) > >>>>> 6. easier to test > >>>>> > >>>>> The only downside I can see is that it might be slightly harder to > >>>>> statically verify that a developer has remembered to address security > >>>>> (in the proposed version you might be able to write a unit tests that > >>>>> asserts that all relevant methods have a non-empty > >>>>> "@RequiresAttributes" annotation). > >>>>> > >>>>> Here are the examples from below rewritten in POJ: > >>>>> > >>>>> Assume the following helper code is imported in each case: > >>>>> > >>>>> public class AuthenticationHelper { > >>>>> public static void assertAuth(bool ok) { > >>>>> if (!ok) { > >>>>> throw new AuthenticationException("Insufficient permissions"); > >>>>> } > >>>>> } > >>>>> > >>>>> public static User currentUser() { > >>>>> // create a domain-specific User class from Shiro's > >>>>> SecurityUtils.getSubject() > >>>>> } > >>>>> } > >>>>> > >>>>> Example of use case #1: > >>>>> > >>>>> public class ProfileEditor { > >>>>> > >>>>> // all users implicitly have permission to edit their own profile, > >>>>> // so don't need RequiresPermissions, but we do need to check > >>>>> // that the profile belongs to this user > >>>>> public void store(Profile userProfile) { > >>>>> assertAuth(currentUser().id == userProfile.userId); > >>>>> > >>>>> // TODO: store the changes > >>>>> } > >>>>> > >>>>> } > >>>>> > >>>>> Example of use case #2: > >>>>> > >>>>> public class Project { > >>>>> List<String> getMemberIds() { > >>>>> // TODO: return list of member ids in this project > >>>>> } > >>>>> > >>>>> // the user has role "project manager" with a "settings:edit" permission > >>>>> // BUT... it's only for this project, not for all projects! > >>>>> @RequiresPermissions("settings:edit") > >>>>> public void editSettings(String key, String newValue) { > >>>>> assertAuth(getMemberIds().contains(currentUser().id)); > >>>>> > >>>>> // TODO: change the setting > >>>>> } > >>>>> > >>>>> } > >>>>> > >>>>> Example of use case #3: > >>>>> > >>>>> public class ClassifiedDocumentRepository { > >>>>> > >>>>> @RequiresPermissions("documents:store") > >>>>> public void storeDocument(@Map("document") Document doc) { > >>>>> assertAuth(currentUser().clearanceLevel >= document.clearanceLevel); > >>>>> // TODO: store the document > >>>>> } > >>>>> > >>>>> // applying access control on return value here with special variable > >>>>> $return > >>>>> @RequiresPermissions("documents:retrieve") > >>>>> public Document retrieveDocument(String documentId) { > >>>>> // TODO: find the document and its metadata > >>>>> > >>>>> Document document = ... > >>>>> > >>>>> assertAuth(currentUser().clearanceLevel >= document.clearanceLevel); > >>>>> return document; > >>>>> } > >>>>> > >>>>> > >>>>> } > >>>>> > >>>>> Best, > >>>>> > >>>>> > >>>>> Rich > >>>>> > >>>>> > >>>>> > >>>>> -----Original Message----- > >>>>> From: jbuhacoff [mailto:[email protected] > >>>>> <mailto:[email protected]>] > >>>>> Sent: 07 July 2016 05:19 > >>>>> To: [email protected] <mailto:[email protected]> > >>>>> Subject: Attribute-based access control > >>>>> > >>>>> Hi, I've been using Shiro for a couple of years now in various projects > >>>>> with annotations and the wildcard permission syntax. Now I have a new > >>>>> requirement for ABAC, and I think it should be possible to add this > >>>>> capability to Shiro. > >>>>> I have a proposal below, and wanted to get some comments. If there's > >>>>> interest, I would develop it myself and contribute the code & > >>>>> documentation. > >>>>> > >>>>> Here are some use cases: > >>>>> > >>>>> 1. a "my profile" or "my settings" feature: user should be able to > >>>>> edit own things but not everything in the table. > >>>>> > >>>>> 2. project or organization based permissions: user should be able to > >>>>> read documents in a project while user is associated with the project > >>>>> or team, possibly combined with a general "can read documents" > >>>>> permission. > >>>>> > >>>>> 3. clearance level: user has a "can read documents" permission but > >>>>> this needs to be matched with the user's clearance level and the > >>>>> document's clearance level. > >>>>> > >>>>> I see attribute-based access control as being a nice complement and > >>>>> orthogonal to the permission-based access control. A given method > >>>>> could be annotated with either one or both together to achieve the > >>>>> right level of control. > >>>>> > >>>>> My proposal is to add a new annotation @RequiresAttributes and to > >>>>> let its > >>>>> value be a boolean expression to be evaluated. Of course the > >>>>> expression will need to be able to refer to the current user, the > >>>>> object in question, and maybe even other things like the time of day, > >>>>> the https client certificate, or whatever. Getting these bits of info > >>>>> into the context of the expression language would be a combination of > >>>>> three things: 1) the realm can set some context when the user is > >>>>> authenticated based on information available at that time (user > >>>>> attributes, connection attributes, etc.) , 2) there could be generic > >>>>> "attribute injectors" like for calendar/time, system properties, or > >>>>> other things that are neither user nor object in question; > >>>>> 3) a new @Map annotation that can be applied to method parameters in > >>>>> order to give them a specific name in the expression. > >>>>> > >>>>> Also there is a special case when we might want to apply > >>>>> attribute-based permissions on the return value of a method. For this > >>>>> we have another annotation @RequiresAttributesOnReturn which would be > >>>>> applied with around advice, calling proceed() and then checking > >>>>> permissions using the return value of the original method bound to a > >>>>> special variable $return. > >>>>> > >>>>> Both @RequiresAttributes and @RequiresAttributesOnReturn would have > >>>>> corresponding methods that could be called directly from anywhere in > >>>>> the code in order to perform the same evaluation without annotations. > >>>>> > >>>>> Special variable $this would be available to expressions annotated on > >>>>> instance methods. > >>>>> > >>>>> Variables and methods of objects would be accessible via dot notation, > >>>>> with automatic use of bean-style "getter" methods when they exist. > >>>>> > >>>>> In all the following examples, $user is a variable bound by the > >>>>> authentication realm to a User object with methods String getId() and > >>>>> Integer getClearanceLevel(). > >>>>> > >>>>> Example of use case #1: > >>>>> > >>>>> public class ProfileEditor { > >>>>> > >>>>> // all users implicitly have permission to edit their own profile, > >>>>> // so don't need RequiresPermissions, but we do need to check > >>>>> // that the profile belongs to this user > >>>>> @RequiresAttributes("$user.id <http://user.id/> = $profile.userId") > >>>>> public void store(@Map("profile") Profile userProfile) { > >>>>> // TODO: store the changes > >>>>> } > >>>>> > >>>>> } > >>>>> > >>>>> Example of use case #2: > >>>>> > >>>>> public class Project { > >>>>> List<String> getMemberIds() { > >>>>> // TODO: return list of member ids in this project > >>>>> } > >>>>> > >>>>> // the user has role "project manager" with a "settings:edit" permission > >>>>> // BUT... it's only for this project, not for all projects! > >>>>> // also special variable $this refers to enclosing class instance > >>>>> @RequiresPermissions("settings:edit") > >>>>> @RequiresAttributes("$this.memberIds.contains($user.id > >>>>> <http://user.id/>)") > >>>>> public void editSettings(String key, String newValue) { > >>>>> // TODO: change the setting > >>>>> } > >>>>> > >>>>> } > >>>>> > >>>>> Example of use case #3: > >>>>> > >>>>> public class ClassifiedDocumentRepository { > >>>>> > >>>>> @RequiresPermissions("documents:store") > >>>>> @RequiresAttributes("$user.clearanceLevel >= $document.clearanceLevel") > >>>>> public void storeDocument(@Map("document") Document doc) { > >>>>> // TODO: store the document > >>>>> } > >>>>> > >>>>> // applying access control on return value here with special variable > >>>>> $return > >>>>> @RequiresPermissions("documents:retrieve") > >>>>> @RequiresAttributesOnReturn("$user.clearanceLevel >= > >>>>> $return.clearanceLevel") > >>>>> public Document retrieveDocument(String documentId) { > >>>>> // TODO: find the document and its metadata > >>>>> return document; > >>>>> } > >>>>> > >>>>> > >>>>> } > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> -- > >>>>> View this message in context: > >>>>> http://shiro-user.582556.n2.nabble.com/Attribute-based-access-control-tp7581093.html > >>>>> > >>>>> <http://shiro-user.582556.n2.nabble.com/Attribute-based-access-control-tp7581093.html> > >>>>> Sent from the Shiro User mailing list archive at Nabble.com. > >>>>> > >>>>> Richard Bradley > >>>>> Tel : 020 7485 7500 ext 3230 | Fax : 020 7485 7575 > >>>>> > >>>>> softwire > >>>>> Sunday Times Best Small Companies - UK top 25 six years running > >>>>> Web : www.softwire.com > >>>>> <http://www.softwire.com/><http://www.softwire.com/ > >>>>> <http://www.softwire.com/>> | Follow us on Twitter : > >>>>> @SoftwireUK<https://twitter.com/SoftwireUK > >>>>> <https://twitter.com/SoftwireUK>> > >>>>> Addr : 110 Highgate Studios, 53-79 Highgate Road, London NW5 1TL > >>>>> Softwire Technology Limited. Registered in England no. 3824658. > >>>>> Registered Office : Gallery Court, 28 Arcadia Avenue, Finchley, London. > >>>>> N3 2FG > >>>>> > >>>> > >>> > >> > > > >
