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

Thread: acess="RUN_AS....

  1. #1
    Join Date
    Dec 2008
    Posts
    9

    Question 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 at 09:43 AM. Reason: typo ... hmmm - can't edit title :(

  2. #2
    Join Date
    Jan 2008
    Posts
    1,826

    Default

    What version of Spring Security are you using? How are you updating the authentication to have the RunAsRole?
    Rob Winch - @rob_winch
    Spring Security Lead
    Pivotal

  3. #3
    Join Date
    Dec 2008
    Posts
    9

    Default

    Quote Originally Posted by Rob Winch View Post
    What version of Spring Security are you using?
    3.1.1

    Quote 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.

  4. #4
    Join Date
    Jan 2008
    Posts
    1,826

    Default

    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).
    Rob Winch - @rob_winch
    Spring Security Lead
    Pivotal

  5. #5
    Join Date
    Dec 2008
    Posts
    9

    Default

    Quote 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.


    Quote 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.


    Quote 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

  6. #6
    Join Date
    Dec 2008
    Posts
    9

    Default

    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.

  7. #7
    Join Date
    Jan 2008
    Posts
    1,826

    Default

    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.
    Rob Winch - @rob_winch
    Spring Security Lead
    Pivotal

  8. #8
    Join Date
    Dec 2008
    Posts
    9

    Default

    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>

  9. #9
    Join Date
    Jan 2008
    Posts
    1,826

    Default

    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?
    Rob Winch - @rob_winch
    Spring Security Lead
    Pivotal

  10. #10
    Join Date
    Dec 2008
    Posts
    9

    Default

    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

Posting Permissions

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