Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Howe to make method interception really works

  1. #1

    Exclamation Howe to make method interception really works

    Hello all,

    I have spent more than two weeks trying to get Method Interception and ACL to work but in vain.. well.. let's not jump to the ACL part because the security interceptor doesn't even get triggered to check for the correct ACE.. the question is if method interception would ever really work??

    I have tried CGLIB proxying and Java Proxying.. and even though CGLIB proxying seems to cause the method interception to work sometimes I had to abandon it because it didn't work with
    <aop:scoped-proxy />
    and I kept getting the same proxy object for all HTTP sessions.. now I use
    <aop:scoped-proxy proxy-target-class="false"/>
    which requires Java interface proxying but at least gives me different Beans for different sessions.

    I have also tried global point cuts, annotations, and the sec namespace XML to define the method inteception.. but all was in vain.

    Any ideas?

    My project uses IceFaces 1.8 with Facelets, Spring Security 2.0.8, and runs on Apache Tomcat 6 and JRE 6.18. The interesting part of the configuration file follows:


    HTML Code:
    	<bean id="wfaclDecisionManager" class="org.springframework.security.vote.UnanimousBased">
    		<property name="allowIfAllAbstainDecisions" value="false" />
    		<property name="decisionVoters">
    			<list>
    				<bean id="roleVoter" class="org.springframework.security.vote.RoleVoter" />
    				<ref local="wfaclCREATEVoter" />
    				<ref local="wfaclEDITVoter" />
    				<ref local="wfaclRELEASEVoter" />
    				<ref local="wfaclDELETEVoter" />
    			</list>
    		</property>
    	</bean>
    
    	<bean id="wfaclCREATEVoter" class="org.springframework.security.vote.AclEntryVoter">
    		<constructor-arg ref="aclService" />
    		<constructor-arg value="WFACL_CREATE" />
    		<constructor-arg>
    			<list>
    				<util:constant
    					static-field="org.bibalex.workflow.storage.WFSVNClientPermission.WFACL_CREATE" />
    			</list>
    		</constructor-arg>
    		<property name="processDomainObjectClass" value="org.bibalex.workflow.storage.SVNFileCreationProtectionArtifact"/>
    	</bean>
    
    <!-- And other entry voters ommitted -->
    	<!--
    		****** Workflow Definition ******
    	-->
    	<bean id="wfStepCREATE" class="org.bibalex.workflow.WFInitiationStep"
    		lazy-init="true">
    
    		<property name="creationProtectionClass"
    			value="org.bibalex.workflow.storage.SVNFileCreationProtectionArtifact" />
    
    		<property name="stepPermission">
    			<util:constant
    				static-field="org.bibalex.workflow.storage.WFSVNClientPermission.WFACL_CREATE" />
    		</property>
    		<property name="stepRole" value="ROLE_CREATOR" />
    
    		<property name="nextStepMap">
    			<map>
    				<entry key="PROCEED" value="EDIT" />
    			</map>
    
    		</property>
    <!--  DON'T DO IT! -->	
    <!--		<sec:intercept-methods-->
    <!--			access-decision-manager-ref="wfaclDecisionManager">-->
    <!--			<sec:protect-->
    <!--				method="complete"-->
    <!--				access="ROLE_CREATOR,WFACL_CREATE" />-->
    <!--		</sec:intercept-methods>-->
    	</bean>
    
    	<bean id="wfStepEDIT" class="org.bibalex.workflow.WFStep"
    		lazy-init="true">
    		<property name="stepPermission">
    			<util:constant
    				static-field="org.bibalex.workflow.storage.WFSVNClientPermission.WFACL_EDIT" />
    		</property>
    		<property name="stepRole" value="ROLE_EDITOR" />
    
    		<property name="nextStepMap">
    			<map>
    				<entry key="PROCEED" value="RELEASE" />
    			</map>
    		</property>
    	
    		<sec:intercept-methods
    			access-decision-manager-ref="wfaclDecisionManager">
    			<sec:protect
    				method="complete"
    				access="ROLE_EDITOR,WFACL_EDIT" />
    		</sec:intercept-methods>
    	</bean>
    
    	<bean id="wfStepRELEASE" class="org.bibalex.workflow.WFStep"
    		lazy-init="true">
    		<property name="stepPermission">
    			<util:constant
    				static-field="org.bibalex.workflow.storage.WFSVNClientPermission.WFACL_RELEASE" />
    		</property>
    		<property name="stepRole" value="ROLE_RELEASER" />
    
    		<property name="nextStepMap">
    			<map>
    				<entry key="ACCEPT" value="DONE" />
    				<entry key="REJECT" value="EDIT" />
    			</map>
    		</property>
    		<sec:intercept-methods
    			access-decision-manager-ref="wfaclDecisionManager">
    			<sec:protect
    				method="complete"
    				access="ROLE_RELEASER,WFACL_RELEASE" />
    		</sec:intercept-methods>
    	</bean>
    
    	<bean id="wfStepDONE" class="org.bibalex.workflow.WFTerminationStep"
    		lazy-init="true">
    	</bean>
    
    
    
    	<!--  ********  WFProcessObject *******  -->
    	<bean id="wamcpWFProcess" class="org.bibalex.workflow.WFProcess"
    		lazy-init="true">
    		<constructor-arg ref="aclService" /> <!--  <property name="aclSvc" ref="aclService"/> -->
    		<constructor-arg ref="wamcpAppDataSource" /> <!-- <property name="datasource" ref="wamcpAppDataSource" /> -->
    		<constructor-arg ref="aclSecurityUtil" />
    		<property name="steps">
    			<map>
    				<entry key="INIT" value-ref="wfStepCREATE" />
    				<entry key="EDIT" value-ref="wfStepEDIT" />
    				<entry key="RELEASE" value-ref="wfStepRELEASE" />
    				<entry key="DONE" value-ref="wfStepDONE" />
    			</map>
    		</property>
    	</bean>
    
    	<!-- ****************** enforcing the workflow ***************** -->
    
    	<!--  This didn't work.. neither the annotations or the pointcuts :D -->
    	<!-- LOOOOOOOOOOOOOL -->	
    	<!--	<sec:global-method-security-->
    	<!--		secured-annotations="enabled"-->
    	<!--		access-decision-manager-ref="wfaclDecisionManager" >-->
    <!---->
    	<!--		<sec:protect-pointcut -->
    	<!--			access="ROLE_CREATOR, WFACL_CREATE" -->
    	<!--
    		expression="execution(*
    		org.bibalex.wamcp.application.WAMCPStorage.add(..))"/>
    	-->
    	<!--	</sec:global-method-security>-->
    
    	<bean class="org.bibalex.workflow.storage.WFSVNClient" id="wfsvnClient"
    		scope="session" lazy-init="true">
    		
    		<aop:scoped-proxy proxy-target-class="false"/>
    	
    		<property name="URL_SVN_ROOT" value="PROTECTED" />
    		<property name="svnUsername" value="PROTECTED.naga" />
    		<property name="svnPassword" value="PROTECTED" />
    		<property name="wfProcess" ref="wamcpWFProcess" />
    		
    		<sec:intercept-methods
    			access-decision-manager-ref="wfaclDecisionManager">
    			<sec:protect
    				method="svn*"
    				access="ROLE_SVNACCESSOR"/>
    			<sec:protect
    				method="add"
    				access="ROLE_CREATOR,WFACL_CREATE" />
    			<sec:protect
    				method="openWrite"
    				access="ROLE_EDITOR,WFACL_EDIT" />
    			<sec:protect
    				method="openRead"
    				access="ROLE_SVNACCESSOR" />
    			<sec:protect
    				method="svnCommit"
    				access="ROLE_EDITOR,WFACL_EDIT" />
    			<sec:protect
    				method="svnRevert"
    				access="ROLE_EDITOR,WFACL_EDIT" />
    <!--			<sec:protect-->
    <!--				method="permitDelete"-->
    <!--				access="ROLE_ADMIN" />-->
    			<sec:protect
    				method="delete"
    				access="ROLE_ADMIN,WFACL_DELETE" />
    			<sec:protect
    				method="requestDelete"
    				access="ROLE_DELETER" />
    			<sec:protect
    				method="unrequestDelete"
    				access="ROLE_DELETER" />
    		</sec:intercept-methods>
    		
    		<property name="proxiedThis" ref="wfsvnClient" />
    		
    	</bean>
    Any help would be greatly appreciated

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    That you receive the same proxy is basically correct. You will get a aop-scoped proxy which lazily delegates to the actual session scoped object. That proxy is the same for everyone.

    Another problem you have is that you have a circulair dependency which probably (or at least might) prevent proper proxy creation.

    Code:
    <property name="proxiedThis" ref="wfsvnClient" />
    You are also using jsf (IceFaces) make sure that you use the spring configured objects and NOTjsf managed the objects, which would basically render your spring configuration useless.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3

    Default

    Hello Martin,

    Thanks for the quick reply.

    As for "You are also using jsf (IceFaces) make sure that you use the spring configured objects and NOTjsf managed the objects, which would basically render your spring configuration useless"... I use only Spring IoC managed beans

    As for the circular dependency.. I actually created it to try to work around that the method interception doesn't work in the cases where I am calling some of the protected methods from the object itself (i don't know if proxying is done by delegation or by inheritence so I wasn't sure what "this" refers tomy object or the proxy) But, this doesn't mean that method interception worked in other cases.. it is just as if it is not there.

    Any other ideas?

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    As for the circular dependency.. I actually created it to try to work around that the method interception doesn't work in the cases where I am calling some of the protected methods from the object itself (i don't know if proxying is done by delegation or by inheritence so I wasn't sure what "this" refers tomy object or the proxy) But, this doesn't mean that method interception worked in other cases.. it is just as if it is not there.
    This reference will lead to eager creation of the bean bypassing proxy creation or at least partially bypassing it, which will eventually lead to issues.

    As for "You are also using jsf (IceFaces) make sure that you use the spring configured objects and NOTjsf managed the objects, which would basically render your spring configuration useless"... I use only Spring IoC managed beans
    In which way are you enforcing this? And are you 100% sure?

    I suggest for starters to remove the ACL stuff to get a testcase as small as possible. Can you post your full configuration (applicationcontext xml files and web.xml? you can put them in a zip file and attach them).
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5

    Default

    Marten,

    Thank you very much.. attached are the configuration files.

    But could you please also tell me if I need to have something similar to my "circular dependency" hack (maybe refactoring into two classes) to insure that method calls from the object itself (using this) will be protected as well?
    Attached Files Attached Files

  6. #6
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    I suggest a read of the reference guide especially the AOP chapter. Spring uses delegation, so this is called on the UNPROXIED instance.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  7. #7

    Default

    I had to do this reading very quickly.. I know it is a difficult subject but my time was so limited.. so I will make sure not to use this.. but still please take a look at the files attached to see if there are other pitfalls in which I had fallen

  8. #8
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    You seem to use a lot of session/request scoped beans, for those to properly work you must use aop:scoped-proxy, without it generally acts like scope prototype. Not sure but some of those beans are candidates for singletons imho (like the manager classes for instance).

    The secured methods, as you are using interface based proxies, have to be defined on the interface if not it will not work. Also if you want to @Secured work you will have to put them on the classes and force classproxying else you will run into trouble.
    Last edited by Marten Deinum; Jul 21st, 2010 at 06:20 AM.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  9. #9

    Default

    The secured methods, as you are using interface based proxies, have to be defined on the interface if not it will not work.
    Uhuhh... now that is something. I was actually using CGLIB proxying until I discovered that it causes the re-use of the same object in all sessions and switched to the Interface proxying.. probably that is where things started to go wrong. Because as I said before, with CGLIB proxying method interception was working in some cases (and not working in the cases where I call using this)... now method interception doesn't work at all.

    So could you please tell me how to define them on the interface? I would like to keep this in the configuration file if possible.. that is, not using the Secured annotations.. because this is part of a reusable Workflow Library.

  10. #10
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    As I mentioned earlier that you get the SAME object is CORRECT... It is a single object which lazily delegates to the ACTUAL session scoped object. So what you think is wrong isn't wrong, your thinking is flawed... IMHO you had it working.

    That the security isn't invoked on this calls common knowledge and stems from the time of EJB. It basically has to do with the fact that proxies are involved. However if you start injecting a this reference you will get eager object creation, which might lead to bypass proxy creation.

    What I meant with define them on the interface is that the methods you want to secure have to be part of your interface...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •