1 2 Previous Next 16 Replies Latest reply on Apr 17, 2012 12:14 PM by baraber Go to original post
      • 15. Re: Permission-based authorization in Seam Faces
        thiagozf

        I don't know if this is a sweet solution, but an alternative would be to create your own @Restrict annotation with a @Nonbinding value (as Shane said), but use @InterceptorBinding instead of @SecurityBindingType. Then, create an interceptor class like this:

         

        @Interceptor

        @Restrict("")

        public class RestrictInterceptor implements Serializable {

                            private static final long serialVersionUID = 1L;

         

                            @AroundInvoke

                      public Object invoke(InvocationContext ctx) throws Exception {          

                  Restrict restrict = getRestrictAnnotation(ctx.getMethod());

                  String value = restricao.value();

                  //now your EL or whatever is in value var

             }

         

             private Restrict getRestrictAnnotation(Method m) {

                          for (Annotation a: m.getAnnotations()) {

                              if (a instanceof Restrict) { return (Restrict) a; }

                          }

                  return null;

             }

         

         

        PS.: don't forget to include the interceptor in the beans.xml.

        • 16. Re: Permission-based authorization in Seam Faces
          baraber

          I still don't know if it's the best way to do, but I made it, based on your suggestion :

           

           

          InterceptorBinding :

           

          {code}

          @InterceptorBinding

          @Retention(RetentionPolicy.RUNTIME)

          @Target({ElementType.METHOD, ElementType.TYPE})

          public @interface Restrict {

              @Nonbinding String value();

          }

          {code}

          Interceptor (Using Solder to resolve EL expressions.):

          {code}

          @Restrict("")

          @Interceptor

          public class RestrictInterceptor implements Serializable {

           

              transient @Inject

              Expressions expressions;

           

              @AroundInvoke

              public Object manageTransaction(InvocationContext ctx) throws Exception {

                  Restrict restrict = getRestrictAnnotation(ctx.getMethod());

           

                  String value = restrict.value();

           

                  try {

                      Boolean hasPermission = expressions.<Boolean>evaluateValueExpression(value);

                      if (hasPermission) {

                          return ctx.proceed();

                      } else {

                          throw new AuthorizationException("Following expression evaluated to false : \"" + value + "\"");

                      }

                  } catch (ELException e) {

                      throw new AuthorizationException(e.getMessage());

                  }

              }

           

              private Restrict getRestrictAnnotation(Method m) {

           

                  for (Annotation a : m.getAnnotations()) {

                      if (a instanceof Restrict) {

                          return (Restrict) a;

                      }

                  }

           

                  return null;

           

              }

          }

          {code}

          Usage example :

          {code}

          @Restrict("#{permissions.has('users', 'create')}")

          public String createUser() {

              ...

          }

          {code}

           

           

          The "permissions" EL name refer to a custom bean that encapsulate calls to "identity.hasPermission(Object, String)" and caches the result in the request scope.
          I do this because I cannot control how many time a sigle permission check will be made in JSF.  ie, the following code will call many time the permission check ( I think I counted about 6 time) :

          {code}

          <h:commandLink action="#{userAction.createUser}" value="Create New User" rendered="#{identity.hasPermission('users', 'create')}"/>

          {code}

           

          I use Rule based security (with drools). 

           

          Just wanted to share a "complete" example.

          1 2 Previous Next