Announcement Announcement Module
Collapse
No announcement yet.
Flex/BlazeDS/Spring Security - Single Session Used by Multiple Browser Sessions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Flex/BlazeDS/Spring Security - Single Session Used by Multiple Browser Sessions

    All,

    I am hoping that someone has come across my issue previously. It is this:

    We are using Flex on the front-end. BlazeDS to integrate Flex with backend Java services and are using the Spring framework. Additionally we are using Spring Security and the Spring/Flex Integration project to do this integration. Authentication is currently being handled using the login() method of the channelset, which subsequently kicks off the typical authentication/authorization steps in spring security using a custom user details service implementation.

    The issue we are seeing is when a user logs into the flex application but doesn't explicitly logout (or continues to use the application). When opening another completely new browser session it is using the session information from the previous, other user's session that is being stored on the server. The first step in our flex application after it loads is to check the server to determine if there is a corresponding session already active, and then automatically login the user to the application if the session already exists. When making the call to the server for this information (via remoting to determine if the user is authenticated) the session info from a completely different browser session, and even across users, machines, etc. will be used and another user's info will be shown b/c it is using their session information. The channelset.login() method is not run in this case and channelset.authenticated isn't currently being checked. Should they be?

    Some of my questions are as follows:

    1. I assume that the use of the preAuthenticationEntryPoint means spring security believes the user has already authenticated. If this is the case, should the Flex call to the service method getZenUser() on startup require the calling of channelset.login() first? How are auto-logins done like this in a typical flex application that integrates with backend sessions?
    2. I've seen/read quite a bit about the session-fixation-protection property on the <http> tag. I've attempted this to no avail.
    3. Interestingly I'm only able to create this issue when connecting to the dataservices that reside on a windows server running IIS and filtering specific requests back to the Tomcat. On my local development machine (Mac) I'm not able to recreate the issue. I also upgraded to the 1.0.1 release of the spring/flex project as I did see there was an existing bug fix for a few items that might affect this.

    I've placed our relevant configuration files below:

    web.xml:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    	<display-name>Zen Data Services</display-name>
    	
    	
    	<context-param>
        	<param-name>contextConfigLocation</param-name>
        	<param-value>
            /WEB-INF/config/services-context.xml
            /WEB-INF/config/security-context.xml
        	</param-value>
    	</context-param>
    	
    	<listener>
    	    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    	
    	<filter>
    		<filter-name>hibernateFilter</filter-name>
    	    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    	</filter>
    	
    	<filter-mapping>
    		<filter-name>hibernateFilter</filter-name>
    		<url-pattern>/web/*</url-pattern>
    	</filter-mapping>
    	
    	<servlet>
    	    <servlet-name>flex</servlet-name>
    	    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>
    				/WEB-INF/config/flex-servlet.xml
    				/WEB-INF/config/security-context.xml
    				/WEB-INF/config/services-context.xml
    			</param-value>
    		</init-param>
    	    <load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<servlet-mapping>
    	    <servlet-name>flex</servlet-name>
    	    <url-pattern>/messagebroker/*</url-pattern>
    	</servlet-mapping>
    
    	<servlet>
    	    <servlet-name>spring-mvc</servlet-name>
    	    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    	   	<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>
    				/WEB-INF/config/spring-mvc-servlet.xml
    			</param-value>
    		</init-param>
    	    <load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<servlet-mapping>
    	    <servlet-name>spring-mvc</servlet-name>
    	    <url-pattern>/web/*</url-pattern>
    	</servlet-mapping>
    
    
    
    	<context-param>
    		<param-name>log4jConfigLocation</param-name>
    		<param-value>/WEB-INF/classes/log4j.xml</param-value>
    	</context-param>
      
    </web-app>

    flex-servlet.xml:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" 
    	xmlns:flex="http://www.springframework.org/schema/flex" 
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xmlns:security="http://www.springframework.org/schema/security"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xsi:schemaLocation=" 
    		http://www.springframework.org/schema/beans
    		http://www.springframework.org/schem...-beans-2.5.xsd
    		http://www.springframework.org/schema/tx 
    		http://www.springframework.org/schem...ing-tx-2.5.xsd 
    		http://www.springframework.org/schema/flex 
    		http://www.springframework.org/schem...g-flex-1.0.xsd
    		http://www.springframework.org/schema/security
    		http://www.springframework.org/schem...rity-2.0.4.xsd
    		http://www.springframework.org/schema/aop 
    		http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    
    	<flex:message-broker>
    		<flex:secured />
    	</flex:message-broker>
    	
    	<!-- Services -->
    	<bean id="selfHelpGuideResponseService" class="com.studentzen.zends.service.SelfHelpGuideResponseService">
    		<property name="zenManager" ref="zenManager" />
    		<flex:remoting-destination />
    		<security:intercept-methods>
    			<security:protect access="ROLE_SELF_HELP_GUIDE_WRITE" method="complete" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_READ" method="getChallengeReferrals" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_READ" method="initiate" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_WRITE" method="log" />
    		</security:intercept-methods> 
    	</bean>
    
    	<bean id="selfHelpGuideService" class="com.studentzen.zends.service.SelfHelpGuideService">
    		<property name="zenManager" ref="zenManager" />
    		<flex:remoting-destination />
    		<security:intercept-methods>
    			<security:protect access="ROLE_SELF_HELP_GUIDE_ADMIN" method="deleteById" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_READ" method="getSummariesByCriteria" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_READ" method="getById" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_ADMIN" method="save" />
    		</security:intercept-methods> 
    	</bean>
    
    	<bean id="sessionService" class="com.studentzen.zends.service.SessionService">
    		<flex:remoting-destination />
    	</bean>
    
    	<bean id="studentRoadMapService" class="com.studentzen.zends.service.StudentRoadMapService">
    		<property name="studentRoadMapEmailHelper" ref="studentRoadMapEmailHelper" />
    		<property name="studentRoadMapReportUrl" value="https://localhost:8443/ZenDS/web/studentRoadMap.pdf" />
    		<property name="zenManager" ref="zenManager" />
    		<flex:remoting-destination />
    		<security:intercept-methods>
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_WRITE" method="addReferral" />
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_WRITE" method="deleteReferral" />
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_EMAIL" method="emailStudentRoadMap" />
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_READ" method="getStudentRoadMapReferrals" />
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_WRITE" method="markReferral" />
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_PRINT" method="printStudentRoadMap" />
    		</security:intercept-methods>
    	</bean>
    
    </beans>

    security-context.xml:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/security"
    	xmlns:beans="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
    		http://www.springframework.org/schem...-beans-2.0.xsd
    		http://www.springframework.org/schema/security 
    		http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"> 
    
    	<http entry-point-ref="preAuthenticatedEntryPoint" />
    
        <beans:bean id="preAuthenticatedEntryPoint" 
            class="org.springframework.security.ui.preauth.PreAuthenticatedProcessingFilterEntryPoint" />
    
        <authentication-provider user-service-ref="zenUserDetailsService">
        	<password-encoder hash="sha">
    			<salt-source user-property="personId" />
        	</password-encoder>
    	</authentication-provider>
    
        <beans:bean id="zenUserDetailsService" class="com.studentzen.zends.security.core.ZenUserDetailsService">
    		<beans:property name="zenManager" ref="zenManager" />
    	</beans:bean></beans:beans>
    services-context.xml

    <Just contains business layer, DAOs and listing of hibernate annotated classes + session factory>

    spring-mvc-servlet.xml:

    <Defines a handler mapping for a pdf we are instantiating from the flex app in a new window>

    Any assistance would be much appreciated. For now the solution is to not perform the initial session check which automatically authenticates the user, which definitely isn't ideal.

    Thank you in advance.

    Alex

  • #2
    Update: Single Session Used by Multiple Browser Sessions

    All,

    It does seem that this is an issue with the way that sessions are being handled on the server. When running apache tomcat 6.0.20 on a windows machine the server session is being reused by separate client connections. Therefore if you login to the flex application in Safari you are authenticated by Spring Security. If I startup a firefox browser session and go to the same Flex url the Flex app will use the existing session on the server that the Safari session was using. If I run Tomcat on the Mac this issue is not experienced.

    From my original post you'll also notice that we have a portion of the application that servers out a report via a separate DispatcherServlet definition and servlet mapping. When running on windows the url to the report can be entered into a browser that shouldn't have access to the server session but it does. On the mac side we get the typical error that the session isn't defined.

    I've placed simpler configuration files below from what I attached previously:

    web.xml

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    	<display-name>Zen Data Services</display-name>
    	
    	<servlet>
    		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>
    				/WEB-INF/config/web-application-security.xml
    				/WEB-INF/config/web-application-config.xml
    			</param-value>
    		</init-param>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<context-param>
    		<param-name>log4jConfigLocation</param-name>
    		<param-value>/WEB-INF/classes/log4j.xml</param-value>
    	</context-param>
    	
    	<!-- Map all /messagbroker requests to the DispatcherServlet for handling -->
    	<servlet-mapping>
    		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    		<url-pattern>/messagebroker/*</url-pattern>
    	</servlet-mapping>    
    </web-app>
    web-application-config.xml

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" 
    	xmlns:flex="http://www.springframework.org/schema/flex" 
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xmlns:security="http://www.springframework.org/schema/security"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xsi:schemaLocation=" 
    		http://www.springframework.org/schema/beans
    		http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    		http://www.springframework.org/schema/tx 
    		http://www.springframework.org/schema/tx/spring-tx-2.5.xsd 
    		http://www.springframework.org/schema/flex 
    		http://www.springframework.org/schema/flex/spring-flex-1.0.xsd
    		http://www.springframework.org/schema/security
    		http://www.springframework.org/schema/security/spring-security-2.0.4.xsd
    		http://www.springframework.org/schema/aop 
    		http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    
    	<flex:message-broker>
    		<flex:secured />
    	</flex:message-broker>
    	
    	<!-- Services -->
    	<bean id="selfHelpGuideResponseService" class="com.studentzen.zends.service.SelfHelpGuideResponseService">
    		<property name="zenManager" ref="zenManager" />
    		<flex:remoting-destination />
    		<security:intercept-methods>
    			<security:protect access="ROLE_SELF_HELP_GUIDE_WRITE" method="complete" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_READ" method="getChallengeReferrals" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_READ" method="initiate" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_WRITE" method="log" />
    		</security:intercept-methods> 
    	</bean>
    
    	<bean id="selfHelpGuideService" class="com.studentzen.zends.service.SelfHelpGuideService">
    		<property name="zenManager" ref="zenManager" />
    		<flex:remoting-destination />
    		<security:intercept-methods>
    			<security:protect access="ROLE_SELF_HELP_GUIDE_ADMIN" method="deleteById" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_READ" method="getSummariesByCriteria" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_READ" method="getById" />
    			<security:protect access="ROLE_SELF_HELP_GUIDE_ADMIN" method="save" />
    		</security:intercept-methods> 
    	</bean>
    
    	<bean id="sessionService" class="com.studentzen.zends.service.SessionService">
    		<flex:remoting-destination />
    	</bean>
    
    	<bean id="studentRoadMapService" class="com.studentzen.zends.service.StudentRoadMapService">
    		<property name="studentRoadMapEmailHelper" ref="studentRoadMapEmailHelper" />
    		<property name="zenManager" ref="zenManager" />
    		<flex:remoting-destination />
    		<security:intercept-methods>
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_WRITE" method="addReferral" />
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_WRITE" method="deleteReferral" />
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_EMAIL" method="emailStudentRoadMap" />
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_READ" method="getStudentRoadMapReferrals" />
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_WRITE" method="markReferral" />
    			<security:protect access="ROLE_STUDENT_ROAD_MAP_PRINT" method="printStudentRoadMap" />
    		</security:intercept-methods>
    	</bean>
    
    	<!-- Business -->
    	<BUSINESS LAYER BEAN DEFINITIONS>
    
    	<!-- Data Access -->
            <DAO LAYER BEAN DEFINITIONS>
    	
    	<tx:annotation-driven />
    	
    	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
    	
    	<!-- Hibernate Session Factory -->
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="annotatedClasses">
    			<list>
                                  <ANNOTATED HIBERNATE CLASSES>
    			</list>
    		</property>
    		<property name="hibernateProperties">
    			<value>
    				hibernate.dialect=org.hibernate.dialect.SQLServerDialect
    				hibernate.show_sql=true
    			</value>
    		</property>
    	</bean>
    	
    	<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName" value="java:comp/env/jdbc/ZenDS"/>
    	</bean>
    	
    	<!-- Email -->
    	<bean id="mailDispatcher" class="com.studentzen.zends.communication.MailDispatcher">
    		<property name="host" value="smtp.gmail.com"/>
    		<property name="protocol" value="smtp"/>
    		<property name="port" value="465"/>
    		<property name="from" value="[email protected]"/>
    		<property name="password" value="YHN8mmMqsQ)WWwEfy8yLrYQLklQcuXrkF3BjmovaaL[sQ5jQ3O"/>
    	</bean>
    	
    	<bean id="velocityTemplateHelper" class="com.studentzen.zends.communication.VelocityTemplateHelper">
    		<property name="velocityEngine" ref="velocityEngine" />
    	</bean>
    	
    	<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
    		<property name="velocityProperties">
    			<value>
    				resource.loader=string
    				string.resource.loader.class=org.apache.velocity.runtime.resource.loader.StringResourceLoader
    			</value>
    		</property>
    	</bean>
    	
    	<bean id="studentRoadMapEmailHelper" class="com.studentzen.zends.communication.StudentRoadMapEmailHelper">
    		<property name="mailDispatcher" ref="mailDispatcher" />
    		<property name="velocityTemplateHelper" ref="velocityTemplateHelper" />
    		<property name="zenManager" ref="zenManager" />
    	</bean>
    
    </beans>
    web-application-security.xml

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/security"
    	xmlns:beans="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
    		http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    		http://www.springframework.org/schema/security 
    		http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"> 
    
    	<http entry-point-ref="preAuthenticatedEntryPoint" />
    
        <beans:bean id="preAuthenticatedEntryPoint" 
            class="org.springframework.security.ui.preauth.PreAuthenticatedProcessingFilterEntryPoint" />
    
        <authentication-provider user-service-ref="zenUserDetailsService">
        	<password-encoder hash="sha">
    			<salt-source user-property="personId" />
        	</password-encoder>
    	</authentication-provider>
    
        <beans:bean id="zenUserDetailsService" class="com.studentzen.zends.security.core.ZenUserDetailsService">
    		<beans:property name="zenManager" ref="zenManager" />
    	</beans:bean>
    
    </beans:beans>
    Again, I appreciate any assistance you can offer. The fact that the two environments both running the same versions of tomcat and java are producing different results is puzzling.

    Alex

    Comment


    • #3
      Indeed, this is puzzling and does not sound like the expected behavior of Tomcat. The session is generally tracked by a cookie that is sent along with each request. It doesn't make sense that this cookie would get re-used between different browsers.

      Have you tested this on Windows without having IIS involved at all? I wonder if it could be causing the problem. I'll do some quick tests myself today to try and reproduce. The newly expanded security demo in the Test Drive in 1.0.1 should be able to replicate the problem.

      Comment


      • #4
        Jeremy, thanks for the response. I have bypassed IIS and still receive the same error. I'll also grab the test drive demo and give it a whirl tonight.

        Thanks,
        Alex

        Comment


        • #5
          Jeremy,

          Just to elaborate further. This is also occurring across separate machines, coming from completely separate IPs, etc.

          If you want to see an example of what is occurring we can share a url for our test instance that has the app installed. Ping me directly if this would be helpful.

          Alex

          Comment


          • #6
            All,

            Problem solved...it helps when you add the filter proxy to web.xml so all requests get routed correctly through the chain.

            Also, so others don't miss this basic step it might be worthwhile to throw it in the Spring BlazeDS reference guide.

            Thanks for the responses.


            Code:
             <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>/*</url-pattern>
                </filter-mapping>

            Comment

            Working...
            X