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

    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
    Richard Barabe Newbie

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

     

     

    InterceptorBinding :

     

    @InterceptorBinding
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD, ElementType.TYPE})
    public @interface Restrict {
        @Nonbinding String value();
    }
    

     

    Interceptor (Using Solder to resolve EL expressions.):

    @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;
    
        }
    }
    

     

    Usage example :

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

     

     

     

    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) :

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

     

     

    I use Rule based security (with drools). 

     

    Just wanted to share a "complete" example.

1 2 Previous Next