Uploaded image for project: 'Shiro'
  1. Shiro
  2. SHIRO-314

Authorization ANTLR Grammar or Expression Language

Details

    Description

      Create a single annotation that would translate the expression into the relevant hasRole/isPermitted calls.

      Details are on wiki https://cwiki.apache.org/confluence/display/SHIRO/Version+2+Brainstorming#Version2Brainstorming-AuthorizationANTLRGrammar .

      Attachments

        1. GrammarDemoProofOfConcept.rar
          1.75 MB
          Maria Jurcovicova
        2. securedAnnotationAuthorizingExpressionLanguage.patch
          72 kB
          Maria Jurcovicova

        Activity

          Demo proof-of-concept parser.

          meri Maria Jurcovicova added a comment - Demo proof-of-concept parser.

          I started with a grammar and would like to get some feedback on it. Demo proof-of-concept parser is in the GrammarDemoProofOfConcept.rar attachment.

          The grammar has four operators:

          • and &&
          • or ||
          • not !
          • parenthesis ( )

          and two build-in functions:

          • role,
          • permission.

          Example:
          @Secured("permission('account:1 0:test') && (permission('print paper') || !role('role'))")

          --------------- Escaping:
          Theoretically, the symbol ' might be used in role or permission name. To escape it, use /.
          Example:
          @Secured("permission('some role with /' symbol')")
          @Secured("role('some role with // symbol')")

          The symbol \ is more standard, but that one has to be escaped in java. E.g. the user would have to write
          role('name with
          ' in it')) instead of role('name with /' in it')) to get "name with ' in it"
          role('name with \\\\ in it')) instead of role('name with // in it')) to get "name with \ in it" or "name with / in it"

          --------------- Shortcut 1:
          As expressions might get too long, both role and permission functions takes n parameters:

          • role(role_1, role_2, ..., role_n),
          • permission(permission_1, permission_2, ..., permission_n).

          Role function returns true if currently logged user has all specified roles. Permission function returns true if currently logged user has all specified permissions.

          Example:
          @Secured("role('traveling sales', 'employee')")
          is equivalent to
          @Secured("role('traveling sales') && role('employee')")

          @Secured("permission('account:1', 'print')")
          is equivalent to
          @Secured("permission('account:1') && permission('print')")

          --------------- Shortcut 2:
          I assume that roles are used more often. If neither role nor permission function is specified, role is assumed.

          Example:
          @Secured("'traveling sales' && 'employee' || 'some role')")
          is equivalent to
          @Secured("role('traveling sales') && role('employee') || role('some role')")

          meri Maria Jurcovicova added a comment - I started with a grammar and would like to get some feedback on it. Demo proof-of-concept parser is in the GrammarDemoProofOfConcept.rar attachment. The grammar has four operators: and && or || not ! parenthesis ( ) and two build-in functions: role, permission. Example: @Secured("permission('account:1 0:test') && (permission('print paper') || !role('role'))") --------------- Escaping: Theoretically, the symbol ' might be used in role or permission name. To escape it, use /. Example: @Secured("permission('some role with /' symbol')") @Secured("role('some role with // symbol')") The symbol \ is more standard, but that one has to be escaped in java. E.g. the user would have to write role('name with ' in it')) instead of role('name with /' in it')) to get "name with ' in it" role('name with \\\\ in it')) instead of role('name with // in it')) to get "name with \ in it" or "name with / in it" --------------- Shortcut 1: As expressions might get too long, both role and permission functions takes n parameters: role(role_1, role_2, ..., role_n), permission(permission_1, permission_2, ..., permission_n). Role function returns true if currently logged user has all specified roles. Permission function returns true if currently logged user has all specified permissions. Example: @Secured("role('traveling sales', 'employee')") is equivalent to @Secured("role('traveling sales') && role('employee')") @Secured("permission('account:1', 'print')") is equivalent to @Secured("permission('account:1') && permission('print')") --------------- Shortcut 2: I assume that roles are used more often. If neither role nor permission function is specified, role is assumed. Example: @Secured("'traveling sales' && 'employee' || 'some role')") is equivalent to @Secured("role('traveling sales') && role('employee') || role('some role')")
          lhazlewood Les Hazlewood added a comment -

          Maria this is one of the biggest features I think for an upcoming release. This is fantastic stuff! Thanks so much for the patch - I'll let you know if I have any issues applying the patch.

          lhazlewood Les Hazlewood added a comment - Maria this is one of the biggest features I think for an upcoming release. This is fantastic stuff! Thanks so much for the patch - I'll let you know if I have any issues applying the patch.
          lhazlewood Les Hazlewood added a comment -

          er - .rar

          lhazlewood Les Hazlewood added a comment - er - .rar

          Hi Les,
          it is not a patch yet, only grammar proposal and demo parser (demonstration that grammar works as it should). I need more time to create a full patch. For now, I assume that there are no objections to my grammar.

          Sorry for the rar format, could not install anything new the computer I am using now .

          meri Maria Jurcovicova added a comment - Hi Les, it is not a patch yet, only grammar proposal and demo parser (demonstration that grammar works as it should). I need more time to create a full patch. For now, I assume that there are no objections to my grammar. Sorry for the rar format, could not install anything new the computer I am using now .

          Patch solves the issue. It changes two sub-projects shiro-aspectj and shiro-core.

          shiro-aspectj:

          • changed pointcut to catch new @Secured annotation,
          • added unit test for @Secured annotation.

          shiro-core:

          • added authorizing expression grammar file (/shiro-core/src/main/antlr3/org/apache/shiro/expressions/parser/AuthorizingExpressions.g),
          • added ANTLR dependency and plugins to pom.xml,
          • added @Secured annotation, its interceptor and handler,
          • added authorization expression language parser and interpreter (org.apache.shiro.expressions package),
          • added unit tests for parser and interpreter.

          Authorization expression language is described in @Secured annotation javadoc.

          meri Maria Jurcovicova added a comment - Patch solves the issue. It changes two sub-projects shiro-aspectj and shiro-core. shiro-aspectj: changed pointcut to catch new @Secured annotation, added unit test for @Secured annotation. shiro-core: added authorizing expression grammar file (/shiro-core/src/main/antlr3/org/apache/shiro/expressions/parser/AuthorizingExpressions.g), added ANTLR dependency and plugins to pom.xml, added @Secured annotation, its interceptor and handler, added authorization expression language parser and interpreter (org.apache.shiro.expressions package), added unit tests for parser and interpreter. Authorization expression language is described in @Secured annotation javadoc.

          Hi,

          I just wanted to ask, whether you had time to try the patch. Was there a problem with it?

          meri Maria Jurcovicova added a comment - Hi, I just wanted to ask, whether you had time to try the patch. Was there a problem with it?
          lhazlewood Les Hazlewood added a comment -

          Hi Maria,

          I personally haven't had the time to try it just yet, but don't worry - I will. I'm excited to see this come to fruition. I'll have to do it when I can step aside from work for a minute. Thanks!

          lhazlewood Les Hazlewood added a comment - Hi Maria, I personally haven't had the time to try it just yet, but don't worry - I will. I'm excited to see this come to fruition. I'll have to do it when I can step aside from work for a minute. Thanks!
          deraj123 Jared Bunting added a comment -

          It would be really nice to be able to include references to parameters passed into the secured methods. Thoughts? I'm writing some similar stuff right now so if others think this seems like a good idea, I should be able to apply that knowledge.

          deraj123 Jared Bunting added a comment - It would be really nice to be able to include references to parameters passed into the secured methods. Thoughts? I'm writing some similar stuff right now so if others think this seems like a good idea, I should be able to apply that knowledge.
          lhazlewood Les Hazlewood added a comment -

          Yes, I think parameter references will be pretty much required. As I understand it though, this will only work if DEBUG is enabled at compilation time, as method parameter names are only available as debug symbols.

          lhazlewood Les Hazlewood added a comment - Yes, I think parameter references will be pretty much required. As I understand it though, this will only work if DEBUG is enabled at compilation time, as method parameter names are only available as debug symbols.
          deraj123 Jared Bunting added a comment -

          The solution that I'm looking at right now involves using an AnnotationProcessor to save off the parameter names at compile time. This also allows us to do compile-time checking of the expression.

          I'm still evaluating if this is too much hocus-pocus, but right now I'm feeling good about it.

          deraj123 Jared Bunting added a comment - The solution that I'm looking at right now involves using an AnnotationProcessor to save off the parameter names at compile time. This also allows us to do compile-time checking of the expression. I'm still evaluating if this is too much hocus-pocus, but right now I'm feeling good about it.

          I think that having an annotation processor is not a bad idea as much of the time the users won't have to worry about it.
          This being said i think we got something here:

          This implementation fit better if say we don't want a dependency on spring for some hypothetical reason and it is a simple but effective way.

          exilire2vie DIALLO Mamadou BObo added a comment - I think that having an annotation processor is not a bad idea as much of the time the users won't have to worry about it. This being said i think we got something here: This implementation fit better if say we don't want a dependency on spring for some hypothetical reason and it is a simple but effective way.
          bdemers Brian Demers added a comment -

          I was hacking on this idea last night, instead of using ANTLR Grammer I created some javax.el function mappings. This is just a POC, and it works slightly different from our other annotations (as this needs access to the method invocation.

          https://github.com/bdemers/shiro/blob/SHIRO-314-el/support/el/src/test/java/org/apache/shiro/el/AnnotatedStub.java

          I added a @ParamName annotation, but we may want to support the JAX-RS QueryParam, PathParm, and Spring equivalent as well.

          I also named the annotation 'RequiresExpression' to match the other Shiro annotations, it might be a bit verbose though.

          Thoughts / Ideas are welcome.

          bdemers Brian Demers added a comment - I was hacking on this idea last night, instead of using ANTLR Grammer I created some javax.el function mappings. This is just a POC, and it works slightly different from our other annotations (as this needs access to the method invocation. https://github.com/bdemers/shiro/blob/SHIRO-314-el/support/el/src/test/java/org/apache/shiro/el/AnnotatedStub.java I added a @ParamName annotation, but we may want to support the JAX-RS QueryParam, PathParm, and Spring equivalent as well. I also named the annotation 'RequiresExpression' to match the other Shiro annotations, it might be a bit verbose though. Thoughts / Ideas are welcome.

          People

            lhazlewood Les Hazlewood
            meri Maria Jurcovicova
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: