Announcement Announcement Module
Collapse
No announcement yet.
acess="RUN_AS.... Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • acess="RUN_AS....

    I have an application in which a user has extra rights when browsing in her own stuff. In order to accomplish this, I have a virtual folder in the application (/my) in which the controller makes sure that the thing that you picked is yours, and displays it to you. I have granted a ROLE_RUN_AS_ME role to this folder in the following way:

    Code:
        <bean
          id="filterInvocationInterceptor"
          class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"
        >
            <property name="authenticationManager" ref="authenticationManager" />
            <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" />
            <property name="runAsManager" ref="runAsManager" />
            <property name="securityMetadataSource">
                <security:filter-security-metadata-source path-type="ant">
                    <security:intercept-url pattern="/home/**" access="ROLE_ANONYMOUS,ROLE_USER" />
                    <security:intercept-url pattern="/my/**" access="ROLE_USER,RUN_AS_ME"  />
                    <security:intercept-url pattern="/search/**" access="ROLE_SYSTEM_SEARCH" />
                    <security:intercept-url pattern="/user/**" access="ROLE_SYSTEM_SEARCH,RUN_AS_SEARCH" />
                    <security:intercept-url pattern="/appl/**" access="ROLE_SYSTEM_APPL" />
                    <security:intercept-url pattern="/area/**" access="ROLE_SYSTEM_AREA" />
                </security:filter-security-metadata-source>
            </property>
        </bean>
    Some users (those who have ROLE_SYSTEM_SEARCH rights) can look at other users' stuff. However, if I have more than one browser window open, and one of those windows is looking at my own stuff, sometimes I have the ROLE_RUN_AS_ME role in the window where I am looking at the other person's stuff. To confirm that this is true, I have added the tag
    Code:
    <authz:authentication property="authorities" />
    at the bottom of my pages. Sometimes the ROLE_RUN_AS_ME is repeated more than once!

    When I am looking at my own stuff, or at someone else's stuff, the same JSP files are being used. The /user/** folder has the ROLE_RUN_AS_SEARCH assigned to help keep track of who's stuff I am viewing. Currently, both of these roles are being assigned at the same time. ... sometimes multiple times.

    Is this a bug, or am I supposed to be doing something differently? Is there a place where I am supposed to tell Spring Security to stop running as...?


    Thanks,

    Paul Hanbury
    Last edited by phanbu; Aug 31st, 2012, 10:43 AM. Reason: typo ... hmmm - can't edit title :(

  • #2
    What version of Spring Security are you using? How are you updating the authentication to have the RunAsRole?

    Comment


    • #3
      Originally posted by Rob Winch View Post
      What version of Spring Security are you using?
      3.1.1

      Originally posted by Rob Winch View Post
      How are you updating the authentication to have the RunAsRole?
      I'm not quite sure what you are asking here. I simply have a RunAsManager bean (of type org.springframework.security.access.intercept.RunA sManagerImpl) defined in my XML file. This is the runAsManager referenced in my code in the original post.

      What it looks like is happening (to me anyway) is that when I click on a link with with a /my/**-shaped URL, the securityInterceptor's beforeInvocation() method calls the runAsManager's buildRunAs() method. This accepts my original Authentication object (which is of type org.springframework.security.authentication.Userna mePasswordAuthenticationToken), a FilterInvocation object (which seems to be ignored), and a Collection of ConfigAttributes (which contains the values "ROLE_USER" and "RUN_AS_ME" from the filterInvocationInterceptor). When it finds the RUN_AS_ME attribute, it creates a new list of authorities containing all of the previous authorities, plus a new ROLE_RUN_AS_ME authority. Then this new list of authorities is used to create a new Authentication object (of type org.springframework.security.access.intercept.RunA sUserToken). Finally, the securityInterceptor saves the old Authentication object so that it can be put back into the security context later (which is done in its afterInvocation() method).

      This is all well and good (at normal speed).

      However, if I rapidly click on a bunch of /my/**-shaped links, then the calls to afterInvocation() happen in the wrong order. Eventually, my original Authentication object is not in the security context (a RunAsUserToken has taken its place.) Unfortunately, this replacement Authentication token still contains the ROLE_RUN_AS_ME authority, even after I have browsed to a different page.

      Comment


      • #4
        The reason I asked the version is due to this issue which should not be present in 3.1.1.

        What does the rest of your configuration look like? Did you ensure to have the SecurityContextPersistenceFilter as the first filter? It is in charge of removing the SecurityContext from the ThreadLocal.

        NOTE: I was able to produce a load of 40 users concurrently requesting a RUN_AS url and a non RUN_AS url without any problems using 3.1.2 (you might try updating to see if that helps).

        Comment


        • #5
          Originally posted by Rob Winch View Post
          What does the rest of your configuration look like?
          I can include the XML in a post here if you want to see it.

          We do have a custom authenticationProcessingFilter and a custom authenticationProvider. These make sure that the right Authentication object put into the security context. I have been looking at these to see if they might be causing problems. However, no method in either of these classes is ever called during a runAs request (just during authentication).

          We are also using Tiles to layout our pages. So we get multiple forwards per request. filterSecurityInterceptor.isObserveOncePerRequest( ) returns true.


          Originally posted by Rob Winch View Post
          Did you ensure to have the SecurityContextPersistenceFilter as the first filter? It is in charge of removing the SecurityContext from the ThreadLocal.
          Our channelProcessingFilter was first in the chain. I have moved it so that now the filter chain looks like this:
          Code:
              <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
                  <security:filter-chain-map path-type="ant">
                      <security:filter-chain
                      pattern="/**"
                      filters
                        ="securityContextPersistenceFilter,
                          channelProcessingFilter,
                          logoutFilter,
                          authenticationProcessingFilter,
                          securityContextHolderAwareRequestFilter,
                          anonymousProcessingFilter,
                          exceptionTranslationFilter,
                          filterInvocationInterceptor"
                    />
                  </security:filter-chain-map>
              </bean>
          Maybe this could be set up differently/better? Still this change didn't fix the problem.


          Originally posted by Rob Winch View Post
          NOTE: I was able to produce a load of 40 users concurrently requesting a RUN_AS url and a non RUN_AS url without any problems using 3.1.2 (you might try updating to see if that helps).
          I did upgrade to 3.1.2. This also does not help either.

          It seems that in AbstractSecurityInterceptor, the afterInvocationManager is null. How can I fix this?

          Thanks,
          Paul

          Comment


          • #6
            If I set a breakpoint at AbstractSecurityInterceptor:259, which says:
            Code:
            SecurityContextHolder.setContext(token.getSecurityContext());
            The first time the code breaks when requesting pages with RUN_AS_... roles, token's securityContext holds a UsernamePasswordAuthenticationToken. But on the second request, it holds a RunAsUserToken.

            Comment


            • #7
              Just out of curiosity what does your web.xml look like? Since you have set observe once per request to true, it should not be relevant relevant but I am wondering if SS is setup to execute on multiple dispatch types.

              PS: If you can produce a small project that reproduces the issue, I would be happy to look at it for you. If you are using Maven, Gradle, etc for dependency resolution it should fit in a zip file on the forums.

              Comment


              • #8
                Code:
                <?xml version="1.0" encoding="UTF-8"?>
                <web-app
                  version="2.5"
                  xmlns="http://java.sun.com/xml/ns/javaee"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation=
                  "http://java.sun.com/xml/ns/javaee
                   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
                >
                    <!--  ============================================================= -->
                    <!--   APPLICATION DETAILS                                          -->
                    <!--  ============================================================= -->
                    <display-name>User Profiles</display-name>
                    <!--  ============================================================= -->
                
                
                    <!--  ============================================================= -->
                    <!--   SPRING CONFIGURATION                                         -->
                    <!--  ============================================================= -->
                    <context-param>
                        <param-name>contextConfigLocation</param-name>
                        <param-value>
                            /WEB-INF/spring-config/spring-properties.xml
                            /WEB-INF/spring-config/spring-datasource.xml
                            /WEB-INF/spring-config/spring-security.xml
                        </param-value>
                        <!--
                        -->
                    </context-param>
                    <!--  ============================================================= -->
                    
                
                    <!--  ============================================================= -->
                    <!--   HTTP REQUEST FILTER(S)                                       -->
                    <!--  ============================================================= -->
                    <filter>
                        <filter-name>springSecurityFilterChain</filter-name>
                        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
                    </filter>
                    <filter-mapping>
                        <filter-name>springSecurityFilterChain</filter-name>
                        <url-pattern>*.htm</url-pattern>
                        <url-pattern>*.do</url-pattern>
                        <url-pattern>/security/*</url-pattern>
                    </filter-mapping>
                    <!--  ============================================================= -->
                    
                
                    <!--  ============================================================= -->
                    <!--   CONTEXT LISTENER(S)                                          -->
                    <!--  ============================================================= -->
                    <listener>
                        <listener-class>
                            org.springframework.web.context.ContextLoaderListener
                        </listener-class>
                    </listener>
                    <!-- ============================================================= -->
                
                
                    <!-- ============================================================= -->
                    <!--   SERVLET DEFINITIONS                                         -->
                    <!-- ============================================================= -->
                    <!-- Spring servlets -->
                    <servlet>
                        <servlet-name>webapp</servlet-name>
                        <servlet-class>
                            org.springframework.web.servlet.DispatcherServlet
                        </servlet-class>
                        <init-param>
                            <param-name>contextConfigLocation</param-name>
                            <param-value>
                                /WEB-INF/spring-config/spring-properties.xml
                                /WEB-INF/spring-config/application-servlet.xml
                            </param-value>
                        </init-param>
                        <load-on-startup>1</load-on-startup>
                    </servlet>
                    
                    <servlet>
                        <servlet-name>monitor</servlet-name>
                        <servlet-class>
                            org.springframework.web.servlet.DispatcherServlet
                        </servlet-class>
                        <init-param>
                            <param-name>contextConfigLocation</param-name>
                            <param-value>
                                /WEB-INF/spring-config/spring-properties.xml
                                /WEB-INF/spring-config/monitor-servlet.xml
                            </param-value>
                        </init-param>
                        <load-on-startup>2</load-on-startup>
                    </servlet>
                    
                    <!-- HSConnect servlets -->
                    <servlet>
                        <servlet-name>HSC Login Servlet</servlet-name>
                        <servlet-class>edu.pitt.health.core.security.authc.hsc.HscLoginServlet</servlet-class>
                        <init-param>
                            <param-name>properties</param-name>
                            <param-value>hsconnect.properties</param-value>
                        </init-param>
                        <load-on-startup>3</load-on-startup>
                    </servlet>
                
                    <servlet>
                        <servlet-name>HSC Logout Servlet</servlet-name>
                        <servlet-class>edu.pitt.health.core.security.authc.hsc.HscLogoutServlet</servlet-class>
                        <init-param>
                            <param-name>properties</param-name>
                            <param-value>hsconnect.properties</param-value>
                        </init-param>
                        <load-on-startup>4</load-on-startup>
                    </servlet>
                    <!-- ============================================================= -->
                
                
                    <!-- ============================================================= -->
                    <!--   SERVLET MAPPINGS                                            -->
                    <!-- ============================================================= -->
                    <!-- Spring servlet mappings -->
                    <servlet-mapping>
                        <servlet-name>webapp</servlet-name>
                        <url-pattern>*.do</url-pattern>
                        <url-pattern>*.htm</url-pattern>
                    </servlet-mapping>
                    <servlet-mapping>
                        <servlet-name>monitor</servlet-name>
                        <url-pattern>/monitoring/*</url-pattern>
                    </servlet-mapping>
                    
                    <!--  HSC login servlet mapping -->
                    <servlet-mapping>
                        <servlet-name>HSC Login Servlet</servlet-name>
                        <url-pattern>/security/hsc_login</url-pattern>
                    </servlet-mapping>
                    <servlet-mapping>
                        <servlet-name>HSC Logout Servlet</servlet-name>
                        <url-pattern>/security/hsc_logout</url-pattern>
                    </servlet-mapping>
                    <!-- ============================================================= -->
                
                
                    <!-- ============================================================= -->
                    <!--  OTHER CONFIGURATION OPTIONS                                  -->
                    <!-- ============================================================= -->
                    <!-- Session timeout -->
                    <session-config>
                        <session-timeout>
                            30
                        </session-timeout>
                    </session-config>
                    <!-- ============================================================= -->
                    <!-- Default filename listing -->
                    <welcome-file-list>
                        <welcome-file>index.jsp</welcome-file>
                    </welcome-file-list>
                    <!-- ============================================================= -->
                
                </web-app>

                Comment


                • #9
                  Still don't see anything that jumps out as different from my sample application from yours. Are you able to produce a sample app that reproduces the problem?

                  Comment


                  • #10
                    Hi, Rob.

                    I am currently working on a solution to this problem that does not use RunAs features.
                    I may try to write a simpler web application that demonstrates this problem in the near future.

                    Thanks for your time,
                    Paul

                    Comment


                    • #11
                      Originally posted by phanbu View Post
                      I may try to write a simpler web application that demonstrates this problem in the near future.
                      That would be much appreciated.

                      Cheers,

                      Comment


                      • #12
                        By the way here is the sample application along with the JMeter Script that I used to try to reproduce the problem. As mentioned previously, I was unsuccessful at reproducing the issue though.

                        Comment

                        Working...
                        X