There is also SHIRO-417, which is somewhat related. I started applying the
patch this morning, but I wanted to make sure we had a holistic solution
(syntax, parameter annotation usage, etc), before continuing.



On Thu, Jul 7, 2016 at 10:51 AM, Lenny Primak <[email protected]>
wrote:

> 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
>
>
> 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
>> <http://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
>> >>>>>
>> >>>>
>> >>>
>> >>
>> >
>>
>>
>
>

Reply via email to