Auth annotation with spring not work

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Auth annotation with spring not work

cdangelo
Hi all,
I'm using dwr 3.0 RC3 with spring.
I've configured the context with
<dwr:configuration></dwr:configuration>
<dwr:controller id="dwrController" debug="true"></dwr:controller>
<dwr:annotation-config></dwr:annotation-config>
<dwr:annotation-scan base-package="it.twell.controllers.ajax" />

My dwr class is:
@RemoteProxy
public class CollaboratoriAjax {


     @RemoteMethod
     @Auth(role="hasRole('admin')")
     public List<Utente> findUtenti(String filtro) {
         return null;
     }
}

And I've implemented an access control to use with spring security

public class DWRAccessControl extends DefaultAccessControl {

     @Override
     protected void assertRoleRestriction(String scriptName, String
methodName) {
         Set<String> roles = getRoleRestrictions(scriptName, methodName);
         if (roles != null && !roles.isEmpty())  {
             String role = roles.iterator().next();

             SecurityExpressionHandler<FilterInvocation> handler;
             Expression accessExpression;
             try {
                 handler = this.getExpressionHandler();
                 accessExpression =
handler.getExpressionParser().parseExpression(role);

             } catch (Exception e) {
                 throw new RuntimeException(e);
             }

             boolean value =
ExpressionUtils.evaluateAsBoolean(accessExpression,
createExpressionEvaluationContext(handler));
             if(!value)
                 throw new AccessDeniedException("Utente non autorizzato");
         }
     }
...
The getRoleRestrictions(scriptName, methodName); return null.
The problem is that... the @Auth annotation is not used in
CreatorParserHelper.registerCreator(definitionHolder, registry,
beanDefinitionClass, javascript)

                 for (Method method : beanDefinitionClass.getMethods()) {
                     if (method.getAnnotation(RemoteMethod.class) != null)
                     {
                         includes.add(method.getName());
                     }
                 }


I've need to set authorization in dwr methods but I can't go on.

Sincerally

Claudio

Reply | Threaded
Open this post in threaded view
|

Re: Auth annotation with spring not work

ememisya
This is expected.  For example @Valid also doesn't work given it's
@RequestMapping annotation of Spring which checks for it.  My suggestion
to you is to use aspectJ.

Take a look at the code below:

   /**
    * Calls <b>validate()</b> on the annotated method and injects the
    * resulting @code{Set<ConstraintViolation>} into the second
    * parameter of the method.  As well as performing additional context
    * based validation annotations.
    *
    * @param pjp ProceedingJoinPoint passed by AspectJ
    * @return Object Proceeds down the advice chain.
    * @throws Throwable Any exception
    */
@Around("@annotation(edu.vt.middleware.ed.dat.aspect.ValidatedDWRMethod)")
   public Object validateDWRAnnotations(final ProceedingJoinPoint pjp)
           throws Throwable
   {
     final Object[] args = pjp.getArgs();
     args[1] = ((ValidatableController) pjp.getThis())
             .getValidator()
             .validate(args[0]);
     return pjp.proceed(args);
   }

..... And the annotation ValidatedDWRMethod below:

@Documented
@Target({ ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidatedDWRMethod {

}

Basically I'm wrapping around @ValidatedDWRMethod via AspectJ and
invoking .validate() for the validator myself.  Here's what it looks
like on the DWR side:

   @RemoteMethod
   @ValidatedDWRMethod
   public List<ServiceModel> queryServiceBasicDetails(
           final ServiceQueryCommand serviceQueryCommand,
           final Set<ConstraintViolation> errors)
           throws ValidationException, ApplicationException
   {
     handleBindingErrors(errors); //By the time we get to this
instruction errors is validated.
     serviceQueryCommand.setLoadLazyProperties(false);
     return
populateBasicDetailsModel(this.getQuery().searchServices(serviceQueryCommand));
   }

All validation errors, get stored in the Set<ContraintViolation> which
then gets passed into handleBindingErrors().  As long as I indicate a
@RemoteMethod is @ValidatedDWRMethod the ServiceQueryCommand in the
example will be able to make use of annotations like @NotNull,
@NotEmpty, @Pattern, @Size etc:

from ServiceQueryCommand:
...
@NotNull
   @RemoteProperty
   @Override
   public int getFirstResult()
   {
     return super.getFirstResult();
   }

   @NotNull
   @RemoteProperty
   @Override
   public int getMaxResults()
   {
     return super.getMaxResults();
   }
...

In conclusion using DWR mapping annotations can come at the cost of
losing the call to a few popular framework initiated annotations, but
rolling your own annotation is quick and easy with AspectJ so you can
customize any way you like.

I hope this helps.

Sincerely,

--Erdem "Adam" Memisyazici



On 01/22/2015 09:25 AM, Claudio D'Angelo wrote:

> Hi all,
> I'm using dwr 3.0 RC3 with spring.
> I've configured the context with
> <dwr:configuration></dwr:configuration>
> <dwr:controller id="dwrController" debug="true"></dwr:controller>
> <dwr:annotation-config></dwr:annotation-config>
> <dwr:annotation-scan base-package="it.twell.controllers.ajax" />
>
> My dwr class is:
> @RemoteProxy
> public class CollaboratoriAjax {
>
>
>     @RemoteMethod
>     @Auth(role="hasRole('admin')")
>     public List<Utente> findUtenti(String filtro) {
>         return null;
>     }
> }
>
> And I've implemented an access control to use with spring security
>
> public class DWRAccessControl extends DefaultAccessControl {
>
>     @Override
>     protected void assertRoleRestriction(String scriptName, String
> methodName) {
>         Set<String> roles = getRoleRestrictions(scriptName, methodName);
>         if (roles != null && !roles.isEmpty())  {
>             String role = roles.iterator().next();
>
>             SecurityExpressionHandler<FilterInvocation> handler;
>             Expression accessExpression;
>             try {
>                 handler = this.getExpressionHandler();
>                 accessExpression =
> handler.getExpressionParser().parseExpression(role);
>
>             } catch (Exception e) {
>                 throw new RuntimeException(e);
>             }
>
>             boolean value =
> ExpressionUtils.evaluateAsBoolean(accessExpression,
> createExpressionEvaluationContext(handler));
>             if(!value)
>                 throw new AccessDeniedException("Utente non
> autorizzato");
>         }
>     }
> ...
> The getRoleRestrictions(scriptName, methodName); return null.
> The problem is that... the @Auth annotation is not used in
> CreatorParserHelper.registerCreator(definitionHolder, registry,
> beanDefinitionClass, javascript)
>
>                 for (Method method : beanDefinitionClass.getMethods()) {
>                     if (method.getAnnotation(RemoteMethod.class) != null)
>                     {
>                         includes.add(method.getName());
>                     }
>                 }
>
>
> I've need to set authorization in dwr methods but I can't go on.
>
> Sincerally
>
> Claudio
>

Reply | Threaded
Open this post in threaded view
|

Re: Auth annotation with spring not work

Mike Wilson
Administrator
In reply to this post by cdangelo
Hi Claudio,

This looks like an issue we should fix but David Marginian is
really the expert in this area. David is unavailable the rest
of this week, so check back next week to see what he says
about it.

Best regards
Mike Wilson

Claudio D'Angelo wrote:

> Hi all,
> I'm using dwr 3.0 RC3 with spring.
> I've configured the context with
> <dwr:configuration></dwr:configuration>
> <dwr:controller id="dwrController" debug="true"></dwr:controller>
> <dwr:annotation-config></dwr:annotation-config>
> <dwr:annotation-scan base-package="it.twell.controllers.ajax" />
>
> My dwr class is:
> @RemoteProxy
> public class CollaboratoriAjax {
>
>
>      @RemoteMethod
>      @Auth(role="hasRole('admin')")
>      public List<Utente> findUtenti(String filtro) {
>          return null;
>      }
> }
>
> And I've implemented an access control to use with spring security
>
> public class DWRAccessControl extends DefaultAccessControl {
>
>      @Override
>      protected void assertRoleRestriction(String scriptName, String
> methodName) {
>          Set<String> roles = getRoleRestrictions(scriptName,
> methodName);
>          if (roles != null && !roles.isEmpty())  {
>              String role = roles.iterator().next();
>
>              SecurityExpressionHandler<FilterInvocation> handler;
>              Expression accessExpression;
>              try {
>                  handler = this.getExpressionHandler();
>                  accessExpression =
> handler.getExpressionParser().parseExpression(role);
>
>              } catch (Exception e) {
>                  throw new RuntimeException(e);
>              }
>
>              boolean value =
> ExpressionUtils.evaluateAsBoolean(accessExpression,
> createExpressionEvaluationContext(handler));
>              if(!value)
>                  throw new AccessDeniedException("Utente non
> autorizzato");
>          }
>      }
> ...
> The getRoleRestrictions(scriptName, methodName); return null.
> The problem is that... the @Auth annotation is not used in
> CreatorParserHelper.registerCreator(definitionHolder, registry,
> beanDefinitionClass, javascript)
>
>                  for (Method method :
> beanDefinitionClass.getMethods()) {
>                      if
> (method.getAnnotation(RemoteMethod.class) != null)
>                      {
>                          includes.add(method.getName());
>                      }
>                  }
>
>
> I've need to set authorization in dwr methods but I can't go on.
>
> Sincerally
>
> Claudio
>

Reply | Threaded
Open this post in threaded view
|

Re: Auth annotation with spring not work

david@butterdev.com
In reply to this post by cdangelo
Sorry it has taken me so long to respond.  I have been out on vacation.  
I have created https://directwebremoting.atlassian.net/browse/DWR-630 to
address this issue.

On 01/22/2015 07:25 AM, Claudio D'Angelo wrote:

> I'm using dwr 3.0 RC3 with spring.
> I've configured the context with
> <dwr:configuration></dwr:configuration>
> <dwr:controller id="dwrController" debug="true"></dwr:controller>
> <dwr:annotation-config></dwr:annotation-config>
> <dwr:annotation-scan base-package="it.twell.controllers.ajax" />
>
> My dwr class is:
> @RemoteProxy
> public class CollaboratoriAjax {
>
>
>     @RemoteMethod
>     @Auth(role="hasRole('admin')")
>     public List<Utente> findUtenti(String filtro) {
>         return null;
>     }
> }
>
> And I've implemented an access control to use with spring security
>
> public class DWRAccessControl extends DefaultAccessControl {
>
>     @Override
>     protected void assertRoleRestriction(String scriptName, String
> methodName) {
>         Set<String> roles = getRoleRestrictions(scriptName, methodName);
>         if (roles != null && !roles.isEmpty())  {
>             String role = roles.iterator().next();
>
>             SecurityExpressionHandler<FilterInvocation> handler;
>             Expression accessExpression;
>             try {
>                 handler = this.getExpressionHandler();
>                 accessExpression =
> handler.getExpressionParser().parseExpression(role);
>
>             } catch (Exception e) {
>                 throw new RuntimeException(e);
>             }
>
>             boolean value =
> ExpressionUtils.evaluateAsBoolean(accessExpression,
> createExpressionEvaluationContext(handler));
>             if(!value)
>                 throw new AccessDeniedException("Utente non
> autorizzato");
>         }
>     }
> ...
> The getRoleRestrictions(scriptName, methodName); return null.
> The problem is that... the @Auth annotation is not used in
> CreatorParserHelper.registerCreator(definitionHolder, registry,
> beanDefinitionClass, javascript)
>
>                 for (Method method : beanDefinitionClass.getMethods()) {
>                     if (method.getAnnotation(RemoteMethod.class) != null)
>                     {
>                         includes.add(method.getName());
>                     }
>                 }