Page 2 of 2 FirstFirst 12
Results 11 to 15 of 15

Thread: After Invocation Collection Filtering From an EJB (Stateless Session Bean)

  1. #11
    Join Date
    Aug 2011
    Posts
    11

    Default

    Marten,

    My code retireves the clientAPIBean from JNDI in the ServiceImpl class. Once it obtains the clientAPIBean, it calls the retieveItems method. I am now trying to convert the code so it retrieves the clientAPIBean from the spring application context instead. This is probably why the method call is not intercepted. I will keep you posted.

    Thank you!

  2. #12
    Join Date
    Aug 2011
    Posts
    11

    Default

    I want to know HOW do you use/access the clientAPI from your code... My guess is that you do not use this.
    The clientAPIBean is retrieved via JNDI by the SeviceImpl class which then calls the retrieveItems method. I modifed the ServiceImpl class so it retrieves the clientAPIBean from the spring context instead.

    Snippet from SeviceImpl.java:

    Code:
    ...
        ValueSearchResult<ItemValue> searchResult = this.getClientApiFromSpring().retrieveItems(searchParams);
    ...
        private ClientAPI getClientApiFromSpring() {
        	ClientAPI clientAPI;
        	BeanFactoryReference bf = ContextSingletonBeanFactoryLocator.getInstance().useBeanFactory("context");
        	clientAPI = (clientAPI) bf.getFactory().getBean("clientAPIBean");		
        	return rdmsClientAPI;
        }
    ...
    In the log I can see that the clientAPIBean is successfully retrieved from the spring context and the call to retrieveItems worked as my UI is showing the search results as expected.

    Code:
    ...
    2011-08-25 14:01:38,734 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Returning cached instance of singleton bean 'context'
    2011-08-25 14:01:38,734 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Returning cached instance of singleton bean 'clientAPIBean'
    2011-08-25 14:01:38,734 DEBUG [org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean] Trying to create reference to local EJB
    2011-08-25 14:01:38,734 DEBUG [org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean] Obtained reference to local EJB: [BaseRemoteObject] home: weblogic.ejb.container.internal.StatelessEJBHomeImpl@136fcc4
    ...
    However, the interceptor is still not triggered! I do not see any AOP interceptor related messages in my logs. If I put a breakpoint in AclEntryAfterInvocationCollectionFilteringProvider .decide(...) it is never called. I also placed one in clientAPIBean.retireveItems and it is called. I printed the stack trace from clientAPIBean.retireveItems:

    Code:
    ...
    2011-08-25 14:01:38,736 INFO  [some.path.web.ejb.ClientAPIBean] java.lang.RuntimeException: Security trace
    	at some.path.web.ejb.ClientAPIBean.retrieveFrameworks(ClientAPIBean.java:304)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
    	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    	at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
    	at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
    	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    	at com.bea.core.repackaged.springframework.jee.spi.MethodInvocationVisitorImpl.visit(MethodInvocationVisitorImpl.java:37)
    	at weblogic.ejb.container.injection.EnvironmentInterceptorCallbackImpl.callback(EnvironmentInterceptorCallbackImpl.java:54)
    	at com.bea.core.repackaged.springframework.jee.spi.EnvironmentInterceptor.invoke(EnvironmentInterceptor.java:50)
    	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    	at com.bea.core.repackaged.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    	at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
    	at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
    	at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    	at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    	at $Proxy339.retrieveFrameworks(Unknown Source)
    	at some.path.web.ejb.ClientAPIBean_6no8ps_ClientAPIImpl.__WL_invoke(Unknown Source)
    	at weblogic.ejb.container.internal.SessionRemoteMethodInvoker.invoke(SessionRemoteMethodInvoker.java:40)
    	at some.path.web.ejb.ClientAPIBean_6no8ps_ClientAPIImpl.retrieveFrameworks(Unknown Source)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.ejb.access.LocalSlsbInvokerInterceptor.invokeInContext(LocalSlsbInvokerInterceptor.java:71)
    	at org.springframework.ejb.access.AbstractSlsbInvokerInterceptor.invoke(AbstractSlsbInvokerInterceptor.java:189)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    	at $Proxy337.retrieveFrameworks(Unknown Source)
    	at some.path.gwt.server.ServiceImpl.getAllFrameworks(ServiceImpl.java:725)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:562)
    	at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:188)
    	at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:224)
    	at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    	at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    	at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    	at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
    	at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:183)
    	at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3717)
    	at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
    	at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    	at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    	at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
    	at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
    	at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
    	at weblogic.work.ExecuteThread.execute(ExecuteThread.java:207)
    ...
    Is there anything else I can try?

    Thanks!

    PS: You can PM me your email if you want the full logs and config files.

  3. #13
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,629

    Default

    You should simply inject the dependency into your bean and not retrieve it (that would also save a dependency on spring) if you don't use the configuration from spring it is pretty useless to configure at the first place .

    Check your PM for my email...
    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

  4. #14
    Join Date
    Aug 2011
    Posts
    11

    Default

    Hi,

    I pretty much gave up on the method interceptor problem. I decided to move on with my proof of concept by manually invoking the AclEntryAfterInvocationCollectionFilteringProvider from my EJB. Here is my solution.

    Here is the context.xml file. Note that I am not using spring's authentication as users are already logged in and a principal object exists in the EJB context.
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:security="http://www.springframework.org/schema/security"
    	xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    		http://www.springframework.org/schema/security	http://www.springframework.org/schema/security/spring-security-3.0.xsd
    		http://www.springframework.org/schema/util	http://www.springframework.org/schema/util/spring-util-3.0.xsd
    		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
    	">
    
    	<!-- ACL Service Configuration -->
    	<bean id="aclService"
    		class="org.springframework.security.acls.jdbc.JdbcAclService">
    		<constructor-arg ref="dataSource" />
    		<constructor-arg ref="lookupStrategy" />
    		<constructor-arg ref="aclCache" />
    	</bean>
    
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    		destroy-method="close">
    		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
    		<property name="url" value="jdbc:oracle:thin:@the:1521:oss" />
    		<property name="username" value="edufresne" />
    		<property name="password" value="ossadmin" />
    	</bean>
    
    	<bean class="org.springframework.security.acls.jdbc.BasiLookupStrategy" id="lookupStrategy">
    		<constructor-arg ref="dataSource" />
    		<constructor-arg ref="aclCache" />
    		<constructor-arg ref="aclAuthzStrategy" />
    		<constructor-arg ref="aclAuditLogger" />
    	</bean>
    
    	<bean class="some.path.NullAclCache" id="aclCache" />
    
    	<bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"
    		id="aclAuditLogger" />
    
    	<bean
    		class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl"
    		id="aclAuthzStrategy">
    		<constructor-arg>
    			<array>
    				<ref local="aclAdminAuthority" />
    				<ref local="aclAdminAuthority" />
    				<ref local="aclAdminAuthority" />
    			</array>
    		</constructor-arg>
    	</bean>
    
    	<bean
    		class="org.springframework.security.core.authority.GrantedAuthorityImpl"
    		id="aclAdminAuthority">
    		<constructor-arg value="ROLE_ADMIN" />
    	</bean>
    
    	<!-- Collection Filtering Configuration -->
    	<bean id="afterAclCollectionRead"
    		class="org.springframework.security.acls.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider">
    		<constructor-arg ref="aclService" />
    		<constructor-arg>
    			<list>
    				<ref local="aclReadPermission" />
    			</list>
    		</constructor-arg>
    	</bean>
    
    	<bean id="aclReadPermission"
    		class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
    		<property name="staticField">
    			<value>org.springframework.security.acls.domain.BasePermission.READ</value>
    		</property>
    	</bean>
    
    </beans>
    I created the ACL database schema using the SQL scripts provided with spring security. I added data using the following SQL:

    Code:
    insert into acl_class (class) values ('some.path.Item');
    
    insert into acl_sid (principal, sid) values (1, 'someuser');
    
    insert into acl_object_identity (object_id_class,object_id_identity,parent_object,owner_sid,entries_inheriting)
    select cl.id, 12345, null, sid.id, 0
    from acl_class cl, acl_sid sid
    where cl.class='some.path.Item' and sid.sid='someuser';
    
    insert into acl_entry (acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure)
    select oi.id, 1, si.id, 1, 1, 1, 1
    from acl_object_identity oi, acl_sid si
    where si.sid = 'someuser';
    Since the EJB I wanted to secure resides in an EJP project, I could not trigger the initialization of the spring application context in a web.xml because there is no such file. Therefore, for this simple proof of concept, I initialiazed the application context directly from the EJB that is going to use it. I used the @PostConstruct annotation to trigger the initialization of the ClassPathXmlApplicationContext. Here is the EJB's code:

    Code:
    ...
        @Resource
        private EJBContext ejbContext;
    ...
        private ApplicationContext springContext;
    ...
        @PostConstruct
        public void init() {
            springContext = new 
    		ClassPathXmlApplicationContext("classpath*:context.xml");
        }
    ...
        @Override
        public Collection<Items> retrieveAllItems() {
        	
        	Collection<Items> results = ... // obtain the items.
        	
            // --- Filter out the items the requesting user does not have access to ---
    
            // Create an empty authorities collection.
            Collection<GrantedAuthorityImpl> authorities = new ArrayList<GrantedAuthorityImpl>();
            // Create an authentication token containing the principal's info.
            PreAuthenticatedAuthenticationToken preAuthToken = 
                    new PreAuthenticatedAuthenticationToken(ejbContext.getCallerPrincipal(), null, authorities);
            // Create an config collection that hold the required permission name.
            SecurityConfig config = new SecurityConfig("AFTER_ACL_COLLECTION_READ");
            Collection<ConfigAttribute> configs = new ArrayList<ConfigAttribute>();
            configs.add(config);
            // Retrieve the afterAclCollectionRead.
            AclEntryAfterInvocationCollectionFilteringProvider afterAclCollectionRead = 
            	(AclEntryAfterInvocationCollectionFilteringProvider) springContext.getBean("afterAclCollectionRead");
            // Perform the filtering
            Collection<Items> filteredResult = 
    			(Collection<Items>) afterAclCollectionRead.decide(preAuthToken, null, configs, results);
        	
           
            return filteredResult;
        }
    ...
    The code starts by setting up the required spring objects for collection filtering. It creates a list of empty granted authorities. Usually, this list contains the roles the current user has (SIDs). This list is later used to decide if the a collection entry should be kept or not. My example uses the principal's name as the SID so we leave the list of granted authorities empty. The pre-authentication token is the object spring reads the SIDs from. Therefore, we retrieve the EJB's principal information and insert it in this token along with the empty list of granted authorities. Next we need to specify the security configuration to apply when filtering. This is required as the acl entry after invocation collection filtering provider expects to see this config in order to decide if it must filter the collection or not. We can then retrieve the acl entry after invocation collection filtering provider from the application context. Finally, we invoke the decide method manually and let spring security's ACL implementation perform its magic!

    My database only contains two Items instances and only one of them has an ACL entry. Therefore, when I execute the retrievedAllItems method while I am logged on as someuser, I only get the Item that has an ACL entry.

    That's it! Thank you very much for all your support. I hope this solution will be usefull for some of you.

    Cheers!

  5. #15
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,629

    Default

    Why did you give up?!


    The clientAPIBean is retrieved via JNDI by the SeviceImpl class which then calls the retrieveItems method. I modifed the ServiceImpl class so it retrieves the clientAPIBean from the spring context instead.
    Which basically says I don't use the spring configured beans.. To which I replied...

    Quote Originally Posted by mdeinum
    You should simply inject the dependency into your bean and not retrieve it (that would also save a dependency on spring) if you don't use the configuration from spring it is pretty useless to configure at the first place .
    So not sure why you didn't try that...
    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
  •