JSecurity + transaction proxying

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

JSecurity + transaction proxying

mad.rug
Hi

I'm developing a web app, and I'm facing issues with double-proxying... or so I discovered.
My app uses Datanucleus JDO for persistence, and AOP for transacion definition on business methods. When I included JSecurity code (I use version 0.9, waiting for Shiro 1.0) from the sample Spring application (my container is Spring 2.5, and JBoss AS 4.2), my DI of business beans into other beans no longer worked (trace snippet):

org.springframework.beans.TypeMismatchException:
Failed to convert property value of type [$Proxy61 implementing org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,net.sf.cglib.proxy.Factory] to required type [MYPACKAGE.business.MyBean] for property 'myBean';

Some old post somewhere said about double-proxying, and then I figured it must be the reason, because of this JSecurity configuration I included:

<!-- Enable JSecurity Annotations for Spring-configured beans.  Only run after
         the lifecycleBeanProcessor has run: -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" />

I intend to use JSecurity annotation extensively to define security on the business and DAO layers, but also need definition of transactions for business layer, hopefully through AOP.
How can I solve this conflict?

If helpful, this is my spring metadata for transacion AOP (not quite correct, read-only does not work, still working on it):

<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) -->
  <tx:advice id="txAdvice" transaction-manager="txManager">
  <!-- the transactional semantics... -->
  <tx:attributes>
            <tx:method name="store*"/>
            <tx:method name="update*"/>
            <tx:method name="delete*"/>
            <tx:method name="*"  read-only="true"/>
  </tx:attributes>
  </tx:advice>
 
  <!-- ensure that the above transactional advice runs for any execution
    of an operation defined by the FooService interface -->
  <aop:config proxy-target-class="true">
  <aop:pointcut id="defaultServiceOperation" expression="execution(* MYPACKAGE.business..*Bean.*(..))"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="defaultServiceOperation"/>
  </aop:config>

Many thanks!
Reply | Threaded
Open this post in threaded view
|

Re: JSecurity + transaction proxying

Les Hazlewood-2
Hi Mad,

The DefaultAutoProxyAdvisor automatically enabled candidate Advisors by looking at beans as they are instantiated.  In the sample application, it finds the org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor at startup.  This bean subclasses StaticMethodMatcherPointcutAdvisor, which uses Methods as the pointcut mechanism.  If a method is annotated with one of Shiros annotations, its advice is enabled.

The underlying Advice enabled by this mechanism at startup is an instance of:

org.apache.shiro.spring.security.interceptor.AopAllianceAnnotationsAuthorizingMethodInterceptor

You can probably instantiate that directly and just use it in your AOP config.

For example:

<bean id="shiroAnnotationAuthorizationAdvice" class="org.apache.shiro.spring.security.interceptor.AopAllianceAnnotationsAuthorizingMethodInterceptor"/>

...

<aop:advisor advice-ref="shiroAnnotationAuthorizationAdvice" pointcut-ref="..."/>

I haven't tried this myself, but it should lead you down the right path.  Please let us know how it goes.

Regards,

Les

On Mon, Jun 22, 2009 at 5:50 PM, mad rug <[hidden email]> wrote:
Hi

I'm developing a web app, and I'm facing issues with double-proxying... or so I discovered.
My app uses Datanucleus JDO for persistence, and AOP for transacion definition on business methods. When I included JSecurity code (I use version 0.9, waiting for Shiro 1.0) from the sample Spring application (my container is Spring 2.5, and JBoss AS 4.2), my DI of business beans into other beans no longer worked (trace snippet):

org.springframework.beans.TypeMismatchException:
Failed to convert property value of type [$Proxy61 implementing org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,net.sf.cglib.proxy.Factory] to required type [MYPACKAGE.business.MyBean] for property 'myBean';

Some old post somewhere said about double-proxying, and then I figured it must be the reason, because of this JSecurity configuration I included:

<!-- Enable JSecurity Annotations for Spring-configured beans.  Only run after
         the lifecycleBeanProcessor has run: -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" />

I intend to use JSecurity annotation extensively to define security on the business and DAO layers, but also need definition of transactions for business layer, hopefully through AOP.
How can I solve this conflict?

If helpful, this is my spring metadata for transacion AOP (not quite correct, read-only does not work, still working on it):

<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) -->
  <tx:advice id="txAdvice" transaction-manager="txManager">
  <!-- the transactional semantics... -->
  <tx:attributes>
            <tx:method name="store*"/>
            <tx:method name="update*"/>
            <tx:method name="delete*"/>
            <tx:method name="*"  read-only="true"/>
  </tx:attributes>
  </tx:advice>
 
  <!-- ensure that the above transactional advice runs for any execution
    of an operation defined by the FooService interface -->
  <aop:config proxy-target-class="true">
  <aop:pointcut id="defaultServiceOperation" expression="execution(* MYPACKAGE.business..*Bean.*(..))"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="defaultServiceOperation"/>
  </aop:config>

Many thanks!