Take a look at this one: https://issues.apache.org/jira/browse/SHIRO-314
On Thu, Jul 7, 2016 at 4:46 AM, Lenny Primak <[email protected]> wrote: > Ok, you can open an enhancement JIRA with that. > > > On Jul 7, 2016, at 3:43 AM, Richard Adams <[email protected]> > wrote: > > > > Well, Spring Security implements ACL; > > > 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]> 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]> > 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]> 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]> 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]] > >>>>> Sent: 07 July 2016 05:19 > >>>>> To: [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 = $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)") > >>>>> 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 > >>>>> 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/> | Follow us on > Twitter : @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 > >>>>> > >>>> > >>> > >> > > > >
