Announcement Announcement Module
Collapse
No announcement yet.
MethodSecurityInterceptor not working? Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • MethodSecurityInterceptor not working?

    Hello, I'm trying to set up a simple authorization scheme based on roles.
    Some of the accesses are limited by the path:

    Code:
       <bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
          <property name="authenticationManager"><ref bean="authenticationManager"/></property>
          <property name="accessDecisionManager"><ref local="httpRequestAccessDecisionManager"/></property>
          <property name="objectDefinitionSource">
             <value>
    			    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    			    PATTERN_TYPE_APACHE_ANT
    			    /index.jsp=ROLE_ANONYMOUS,ROLE_USER
    			    /logoff.jsp=ROLE_ANONYMOUS,ROLE_USER
    			    /login.jsp=ROLE_ANONYMOUS,ROLE_USER
    				/decorators/**=ROLE_ANONYMOUS,ROLE_USER
    				/images/**=ROLE_ANONYMOUS,ROLE_USER
    				/scripts/**=ROLE_ANONYMOUS,ROLE_USER
    				/styles/**=ROLE_ANONYMOUS,ROLE_USER													
             </value>
          </property>
       </bean>
    But some others I want to filter by method:

    Code:
    	<bean id="securityInterceptor" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
    		<property name="authenticationManager"><ref bean="authenticationManager"/></property>
    		<property name="accessDecisionManager"><ref bean="httpRequestAccessDecisionManager"/></property>
    		<property name="objectDefinitionSource">
    			<value>
    				org.appfuse.web.UserAction.list=ROLE_USER
    				org.appfuse.web.UserAction.save=ROLE_ADMIN
    				org.appfuse.web.UserAction.edit=ROLE_ADMIN
    				org.appfuse.web.UserAction.delete=ROLE_ADMIN
    				org.appfuse.web.UserAction.*=ROLE_USER												
    			</value>
    		</property>
    	</bean>
    The problem is even though I'm logged in as a user with ROLE_USER, it still can call org.appfuse.web.UserAction.edit:

    Here's a piece of the log:
    Code:
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Converted URL to lowercase, from&#58; '/user.do?method=edit&id=1'; to&#58; '/user.do?method=edit&id=1'
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Converted URL to lowercase, from&#58; '/user.do?method=edit&id=1'; to&#58; '/user.do?method=edit&id=1'
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Converted URL to lowercase, from&#58; '/user.do?method=edit&id=1'; to&#58; '/user.do?method=edit&id=1'
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /index.jsp; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /index.jsp; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /index.jsp; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /logoff.jsp; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /logoff.jsp; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /logoff.jsp; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /login.jsp; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /login.jsp; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /login.jsp; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /decorators/**; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /decorators/**; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /decorators/**; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /images/**; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /images/**; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /images/**; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /scripts/**; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /scripts/**; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /scripts/**; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /styles/**; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /styles/**; matched=false
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor25&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /styles/**; matched=false
    &#91;DEBUG,AbstractSecurityInterceptor,http-8080-Processor25&#93; Public object - authentication not attempted
    &#91;DEBUG,AbstractSecurityInterceptor,http-8080-Processor25&#93; Public object - authentication not attempted
    &#91;DEBUG,AbstractSecurityInterceptor,http-8080-Processor25&#93; Authentication object detected and tagged as unauthenticated
    &#91;DEBUG,AbstractSecurityInterceptor,http-8080-Processor25&#93; Authentication object detected and tagged as unauthenticated
    &#91;DEBUG,FilterChainProxy,http-8080-Processor25&#93; /user.do?method=edit&id=1 reached end of additional filter chain; proceeding with original chain
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor23&#93; Converted URL to lowercase, from&#58; '/user.do?method=edit&id=1'; to&#58; '/user.do?method=edit&id=1'
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor23&#93; Converted URL to lowercase, from&#58; '/user.do?method=edit&id=1'; to&#58; '/user.do?method=edit&id=1'
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor23&#93; Converted URL to lowercase, from&#58; '/user.do?method=edit&id=1'; to&#58; '/user.do?method=edit&id=1'
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor23&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /**; matched=true
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor23&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /**; matched=true
    &#91;DEBUG,PathBasedFilterInvocationDefinitionMap,http-8080-Processor23&#93; Candidate is&#58; '/user.do?method=edit&id=1'; pattern is /**; matched=true
    As you can see in the last few lines, a pattern of /** matched my call, but I have no /** defined in my context files.
    Everything seems to be configured OK since this message appears on startup:
    Code:
    &#91;DEBUG,MethodDefinitionMap,main&#93; Adding secure method &#91;org.appfuse.web.UserAction.edit&#93; with attributes &#91;&#91;ROLE_ADMIN&#93;&#93;
    &#91;DEBUG,MethodDefinitionMap,main&#93; Adding secure method &#91;org.appfuse.web.UserAction.edit&#93; with attributes &#91;&#91;ROLE_ADMIN&#93;&#93;
    &#91;DEBUG,MethodDefinitionMap,main&#93; Replacing attributes for secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.edit&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93;&#58; current name &#91;org.appfuse.web.UserAction.edit&#93; is more specific than &#91;org.appfuse.web.UserAction.*&#93;
    &#91;DEBUG,MethodDefinitionMap,main&#93; Replacing attributes for secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.edit&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93;&#58; current name &#91;org.appfuse.web.UserAction.edit&#93; is more specific than &#91;org.appfuse.web.UserAction.*&#93;
    &#91;INFO,MethodDefinitionMap,main&#93; Adding secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.edit&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93; with attributes &#91;&#91;ROLE_ADMIN&#93;&#93;
    &#91;INFO,MethodDefinitionMap,main&#93; Adding secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.edit&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93; with attributes &#91;&#91;ROLE_ADMIN&#93;&#93;
    I'm sure I'm doing something wrong, so I'd appreciate any help on this.

    Thanks,
    Alejandro Sarco

  • #2
    BTW, why every line in the debug log is repeated 2 or even 3 times?

    Comment


    • #3
      Reading through your log, I would think you have two separate SecurityEnforcementFilters being called. You can tell as the FilterChainProxy reaches the end of the chain and then allows the original chain to proceed. I'd thus look at web.xml and ensure it's not defined in there as well.

      In relation to authorization not working correctly, you have no configuration attributes against the HTTP URI "/user.do?method=edit&id=1". As such it is considered public and no authorization or authentication is required. Regarding the MethodSecurityInterceptor protection of org.appfuse.web.UserAction.edit, I agree you certainly seem to have registered the configuration attributes correctly. However, I can't troubleshoot it as there's no logging output related to the MethodSecurityInterceptor-managed invocation of UserAction. Recall UserAction will need to have the MethodSecurityInterceptor advising UserAction in order for any security to be applied (see http://acegisecurity.sourceforge.net...on-aopalliance for more information).

      Comment


      • #4
        Ben, thank you for your reply.

        Here's my web.xml:
        Code:
        	<filter>
                <filter-name>Acegi Filter Chain Proxy</filter-name>
                <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
                <init-param>
                    <param-name>targetClass</param-name>
                    <param-value>net.sf.acegisecurity.util.FilterChainProxy</param-value>
                </init-param>
            </filter>
            <filter-mapping>
              <filter-name>Acegi Filter Chain Proxy</filter-name>
              <url-pattern>/*</url-pattern>
            </filter-mapping>
        and part of my applicationContext-security.xml:
        Code:
        	<bean id="filterChainProxy" class="net.sf.acegisecurity.util.FilterChainProxy">
              <property name="filterInvocationDefinitionSource">
                 <value>
        		    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
        		    PATTERN_TYPE_APACHE_ANT
                    /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,basicProcessingFilter,rememberMeProcessingFilter,anonymousProcessingFilter,securityEnforcementFilter
                 </value>
              </property>
            </bean>
        Do you see anything duplicated in it? Indeed should be something, because everything in my log is twice

        Regarding the authorization, are you saying that if I don't specifiy anything like "user.do*=xxxx" in the specification of FilterSecurityInterceptor, then is public and no authentication is required?
        If so, how should I design a security scheme around Struts dispatch actions? Because if I don't put "user.do*" in FilterSecurityInterceptor, it'll be allowed in, and never will be catched by MethodSecurityInterceptor. However, if I add "user.do*=ROLE_ADMIN", the it'll ask for admin authentication right at the time of the http request, ignoring what's in MethodSecurityInterceptor.

        Even though I added these lines in log4j.xml, no log comes from MethodSecurityInterceptor:

        Code:
        log4j.logger.net.sf.acegisecurity.intercept=DEBUG, stdout, fileout
        log4j.logger.net.sf.acegisecurity.intercept.method=DEBUG, stdout, fileout
        log4j.logger.net.sf.acegisecurity.intercept.method.aopalliance=DEBUG, stdout, fileout
        A little debug inside Eclipse showed that my UserAction is indeed advised, but I couldn't see what the advise is.

        Thanks again.

        Comment


        • #5
          Originally posted by asarco
          Here's my web.xml:
          I suspect your web.xml also contains a separate SecurityEnforcementFilter - that's in addition to the FilterChainProxy that is loading SecurityEnforcementFilter. Check it out and do a search for "net.sf.acegisecurity" in web.xml and confirm it only appears one, being for FilterChainProxy as per your quoted web.xml.

          Originally posted by asarco
          Regarding the authorization, are you saying that if I don't specifiy anything like "user.do*=xxxx" in the specification of FilterSecurityInterceptor, then is public and no authentication is required?
          If so, how should I design a security scheme around Struts dispatch actions? Because if I don't put "user.do*" in FilterSecurityInterceptor, it'll be allowed in, and never will be catched by MethodSecurityInterceptor. However, if I add "user.do*=ROLE_ADMIN", the it'll ask for admin authentication right at the time of the http request, ignoring what's in MethodSecurityInterceptor.

          Even though I added these lines in log4j.xml, no log comes from MethodSecurityInterceptor:

          Code:
          log4j.logger.net.sf.acegisecurity.intercept=DEBUG, stdout, fileout
          log4j.logger.net.sf.acegisecurity.intercept.method=DEBUG, stdout, fileout
          log4j.logger.net.sf.acegisecurity.intercept.method.aopalliance=DEBUG, stdout, fileout
          A little debug inside Eclipse showed that my UserAction is indeed advised, but I couldn't see what the advise is.
          Your MethodSecurityInterceptor for whatever reason isn't being applied to your objects. I suspect there's a misconfiguration - perhaps the object you're trying to advise did not get setup by a ProxyFactoryBean, BeanNameAutoProxyCreator or DefaultAdvisorAutoProxyCreator. You would see some sort of logging if MethodSecurityInterceptor was being used, even if only to report a method is public (ie it has no configuration attributes).

          Having said that, if your objective is to secure Struts Actions, my suggestion would be to do that entirely using FilterSecurityInterceptor (that's what SecurityEnforcementFilter delegates to internally). You do not need to do authorization a second time with a MethodSecurityInterceptor.

          Comment


          • #6
            Ben, there's no other Acegi related filter in my web.xml, but the problem seemed to be related to the log4j configuration file, and not to Acegi itself. Sorry for the inconvenience.

            Now, regarding securing Struts actions, I really need to use method security, because I'm using dispatch actions, and different method in the same action needs different authorization (for example, all users may be able to view the userlist, but only admins could edit a user).

            I don't really know what can be wrong in my configuration, I checked it like a hundred times (of course something may have slipped). Could you please take a look?

            struts-config.xml:
            Code:
                    <action path="/user" type="org.springframework.web.struts.DelegatingActionProxy" 
            			name="userForm" scope="request" parameter="method" validate="false">
                        <forward name="list" path="/userList.do" />
                        <forward name="edit" path="/userForm.do" />
                    </action>
            action-servlet.xml:
            Code:
                <bean name="/user" class="org.appfuse.web.UserAction" singleton="false" autowire="byName">
                    <property name="userManager"><ref bean="userManager"/></property>
                </bean>
            applicationContext-security.xml (relevant pieces):
            Code:
            	<bean id="filterChainProxy" class="net.sf.acegisecurity.util.FilterChainProxy">
                  <property name="filterInvocationDefinitionSource">
                     <value>
            		    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
            		    PATTERN_TYPE_APACHE_ANT
                        /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,rememberMeProcessingFilter,anonymousProcessingFilter,securityEnforcementFilter
                     </value>
                  </property>
                </bean>
            
            	<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
            		<property name="interceptorNames">
            			<list>
            				<value>securityInterceptor</value>
            			</list>
            		</property>
            		<property name="beanNames">
            			<list>
            				<value>/user</value>
            			</list>
            		</property>
            	</bean>
            	
            	<bean id="securityInterceptor" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
            		<property name="authenticationManager"><ref bean="authenticationManager"/></property>
            		<property name="accessDecisionManager"><ref bean="httpRequestAccessDecisionManager"/></property>
            		<property name="objectDefinitionSource">
            			<value>
            				org.appfuse.web.UserAction.list=ROLE_USER
            				org.appfuse.web.UserAction.save=ROLE_ADMIN
            				org.appfuse.web.UserAction.edit=ROLE_ADMIN
            				org.appfuse.web.UserAction.delete=ROLE_ADMIN
            				org.appfuse.web.UserAction.*=ROLE_USER												
            			</value>
            		</property>
            	</bean>
            Log when initializing method interception:
            Code:
            &#91;DEBUG,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;org.appfuse.web.UserAction.*&#93; with attributes &#91;&#91;ROLE_USER&#93;&#93;
            &#91;INFO,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.list&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93; with attributes &#91;&#91;ROLE_USER&#93;&#93;
            &#91;INFO,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.save&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93; with attributes &#91;&#91;ROLE_USER&#93;&#93;
            &#91;INFO,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.delete&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93; with attributes &#91;&#91;ROLE_USER&#93;&#93;
            &#91;INFO,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;public void org.appfuse.web.UserAction.setUserManager&#40;org.appfuse.service.UserManager&#41;&#93; with attributes &#91;&#91;ROLE_USER&#93;&#93;
            &#91;INFO,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.edit&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93; with attributes &#91;&#91;ROLE_USER&#93;&#93;
            &#91;INFO,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.unspecified&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93; with attributes &#91;&#91;ROLE_USER&#93;&#93;
            &#91;DEBUG,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;org.appfuse.web.UserAction.delete&#93; with attributes &#91;&#91;ROLE_ADMIN&#93;&#93;
            &#91;DEBUG,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Replacing attributes for secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.delete&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93;&#58; current name &#91;org.appfuse.web.UserAction.delete&#93; is more specific than &#91;org.appfuse.web.UserAction.*&#93;
            &#91;INFO,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.delete&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93; with attributes &#91;&#91;ROLE_ADMIN&#93;&#93;
            &#91;DEBUG,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;org.appfuse.web.UserAction.edit&#93; with attributes &#91;&#91;ROLE_ADMIN&#93;&#93;
            &#91;DEBUG,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Replacing attributes for secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.edit&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93;&#58; current name &#91;org.appfuse.web.UserAction.edit&#93; is more specific than &#91;org.appfuse.web.UserAction.*&#93;
            &#91;INFO,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.edit&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93; with attributes &#91;&#91;ROLE_ADMIN&#93;&#93;
            &#91;DEBUG,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;org.appfuse.web.UserAction.save&#93; with attributes &#91;&#91;ROLE_ADMIN&#93;&#93;
            &#91;DEBUG,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Replacing attributes for secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.save&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93;&#58; current name &#91;org.appfuse.web.UserAction.save&#93; is more specific than &#91;org.appfuse.web.UserAction.*&#93;
            &#91;INFO,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.save&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93; with attributes &#91;&#91;ROLE_ADMIN&#93;&#93;
            &#91;DEBUG,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;org.appfuse.web.UserAction.list&#93; with attributes &#91;&#91;ROLE_USER&#93;&#93;
            &#91;DEBUG,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Replacing attributes for secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.list&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93;&#58; current name &#91;org.appfuse.web.UserAction.list&#93; is more specific than &#91;org.appfuse.web.UserAction.*&#93;
            &#91;INFO,MethodDefinitionMap,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Adding secure method &#91;public org.apache.struts.action.ActionForward org.appfuse.web.UserAction.list&#40;org.apache.struts.action.ActionMapping,org.apache.struts.action.ActionForm,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse&#41; throws java.lang.Exception&#93; with attributes &#91;&#91;ROLE_USER&#93;&#93;
            &#91;INFO,AbstractSecurityInterceptor,ContainerBackgroundProcessor&#91;StandardEngine&#91;Catalina&#93;&#93;&#93; Validated configuration attributes
            Thanks,

            Comment


            • #7
              I suspect the core of your problem is Spring's AOP is not applying the MethodSecurityInterceptor to your /user bean.

              Try checking your AOP-related logging:

              Code:
              log4j.logger.org.springframework.aop.framework.autoproxy=DEBUG, stdout, fileout
              log4j.logger.org.springframework.aop.framework.autoproxy.metadata=DEBUG, stdout, fileout
              log4j.logger.org.springframework.aop.framework.autoproxy.target=DEBUG, stdout, fileout

              Comment


              • #8
                Yes, that was the problem.

                Seems like the bean definitions in action-servlet.xml were loaded into a different appcontext than the ones in applicationContext-security.xml, so they didn't see each other, so the "/user" bean was not seen by the MethodSecurityInterceptor, and no advise was applied.
                (I didn't find a reference to this in the Spring documentation, so I don't actually understand how do this works, any explanation is welcome).

                Once I moved some bean definitions, the advises were applied. However, I found another problem. Since Struts' DispatchAction calls their methods through reflection, there is no direct call to the methods, therefore no interception is done.

                Would be possible to create something to be able to intercept DispatchAction methods? Something like DispatchActionMethodSecurityInterceptor?

                Thanks a lot, Ben.

                Comment


                • #9
                  Originally posted by asarco
                  Would be possible to create something to be able to intercept DispatchAction methods? Something like DispatchActionMethodSecurityInterceptor?
                  I suspected Struts might be using reflection instead of a bean from the app context. Unfortunately I'm not a Struts user and can't really offer any suggestions. Aside from best practice: use Spring MVC instead (sorry, couldn't help it!) :-)

                  An alternative would be to not use method interception on the Struts actions at all. Struts actions should eventually go to a services layer. That would be the ideal place to put your method invocation security. Also don't dismiss using filter invocation security in conjunction, to prevent the Struts actions being invoked to begin with.

                  At a technical level you could probably develop a DispatchActionMethodSecurityInterceptor. Even if it was just a base Struts Action that used a template method to perform the actual action logic after the authorization checks. But again, I'd have to wonder whether it's truly necessary.

                  Comment


                  • #10
                    Thanks you Ben.
                    Yes, I would like to use Spring MVC, but Struts it's a client requirement.
                    I will resort to the service layer to provide this additional security I need.

                    Thanks again for a great software.

                    Comment


                    • #11
                      Originally posted by asarco View Post

                      Once I moved some bean definitions, the advises were applied. However, I found another problem. Since Struts' DispatchAction calls their methods through reflection, there is no direct call to the methods, therefore no interception is done.
                      Dear asarco,
                      Can you please explain the changes you did, in the bean defenitions?
                      I have the same problem.

                      Comment


                      • #12
                        An alternative would be to not use method interception on the Struts actions at all. Struts actions should eventually go to a services layer. That would be the ideal place to put your method invocation security. Also don't dismiss using filter invocation security in conjunction, to prevent the Struts actions being invoked to begin with.
                        It seems that was the solution that was used. We also use Struts and do this, I think it makes more sense anyway.

                        Comment


                        • #13
                          MethodSecurityInterceptor is not working

                          Hi,

                          I have configured MethodSecurityInterceptor for ACL purpose.
                          I have an interface where all business methods are declared and then i have an abstract base class which implements few of the methods declare in the interface and other methods are implemented by concrete classes.
                          Now I wanna intercept method invocations to the concrete classes for the methods define in concrete classes as well as in abstract class.
                          I am adding all the methods defined in the base interface in to the objectDefinitionSource of the MethodSecurityInterceptor as these are implemented by either of abstract class or the concrete classes.
                          Now i am using BeanNameAutoProxyCreator bean to apply this interceptor to all the concrete classes. but what i found is that spring is not intercepting method calls for the methods defined in the abstract class.
                          When I created a separate concrete class backed by a separate interface it's working fine.
                          I guess problem is with Spring IOC container not with the ACEGI. Does anybody has faced this kind of problem before? I don't know how to fix this
                          Any help is much appreciated.

                          Thanks
                          Sunil
                          Last edited by pratap_sunil; Mar 28th, 2008, 09:16 AM.

                          Comment


                          • #14
                            How are you configuring method security?

                            There are a few issues relating to it which have been resolved for the 2.0 release.

                            http://jira.springframework.org/browse/SEC-99
                            http://jira.springframework.org/browse/SEC-429

                            You might want to try with the latest 2.0 snapshot.

                            Comment


                            • #15
                              Method Security Interceptor not working

                              Thanks Luke for your reply.

                              I am configuring method security in the following way:


                              <!-- Method Security Interceptor -->

                              <bean id="abcdSecurityInterceptor" class="org.acegisecurity.intercept.method.aopallia nce.MethodSecurityInterceptor">
                              <property name="authenticationManager" ref="authenticationManager"/>
                              <property name="accessDecisionManager">
                              <ref local="businessAccessDecisionManager"/>
                              </property>
                              <property name="afterInvocationManager">
                              <ref local="afterInvocationManager"/>
                              </property>
                              <property name="objectDefinitionSource">
                              <value>
                              com.abcd.core.entity.EntityDao.getAllEntities=ROLE _CLIENT,AFTER_ACL_COLLECTION_READ </value>
                              </property>
                              </bean>



                              <!-- Bean Proxy configuration -->

                              <bean id="autoProxyCreator"
                              class="org.springframework.aop.framework.autoproxy .BeanNameAutoProxyCreator">
                              <property name="interceptorNames">
                              <list>
                              <idref bean="abcdSecurityInterceptor" />
                              </list>
                              </property>
                              <property name="beanNames">
                              <list>
                              <value>*Dao</value>
                              </list>
                              </property>
                              </bean>


                              <!-- Beans configuration -->

                              <bean id="customEntityDao" class="com.abcd.core.entity.CustomEntityDaoImpl"
                              lazy-init="default" autowire="default"
                              dependency-check="default">
                              </bean>


                              Above mentioned CustomEntityDaoImpl class extends AbstractEntityDao which partially implements EntityDao interface, on which method security is applied.
                              I have some methods which are implemented in AbstractEntityDao and rest are implemented in CustomEntityDaoImpl. The method getAllEntities is implemented in AbstractEntityDao and when i'm calling getAllEntities on CustomEntityDaoImpl, MethodSecurityInterceptor doesn't work. Even I have added com.abcd.core.entity.AbstractEntityDao.getAllEntit ies in to the objectDefinitionSource of the MethodSecurityInterceptor it's not working.
                              I tried my last effort and I implemented getAllEntities in concrete class CustomEntityDaoImpl, it didn't work either.


                              When I have removed AbstractEntityDao from the inheritence tree and directly implemented EntityDao.getAllEntities in CustomEntityDaoImpl method interception working properly. But I need to support AbstractEntityDao as lots of other Daos are extending this class and common methods are implemented in this class.

                              I am using acegi-security-1.0.5 and new acls package's classes.
                              Last edited by pratap_sunil; Mar 31st, 2008, 10:03 AM.

                              Comment

                              Working...
                              X