Announcement Announcement Module
Collapse
No announcement yet.
ConcurrentSessionFilter configuration problem Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • ConcurrentSessionFilter configuration problem

    Hi,

    I'm trying to get ConcurrentSessionFilter working in a cluster. As a first step, I tried to configure it on one node only. My web.xml includes the needed HttpSessionEventPublisher and my Spring Security configuration is this:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:sec="http://www.springframework.org/schema/security"  
    	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.1.xsd">
    
    	<sec:http access-decision-manager-ref="accessDecisionManager">
    		<!--  login stuff -->
    		<sec:intercept-url pattern="/style/*" access="IS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_FULLY"/>
    		<sec:intercept-url pattern="/images/*" access="IS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_FULLY"/>
    		<sec:intercept-url pattern="/isomorphic/**" access="IS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_FULLY"/>
    		<sec:intercept-url pattern="/acegilogin.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_FULLY"/>
    
            <!-- httpinvoker remoting bindings -->
    		<sec:intercept-url pattern="/remoting/*" access="IS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_FULLY"/>
    		<!-- Sygno Client jnlp -->
    		<sec:intercept-url pattern="/javaws/*" access="IS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_FULLY"/>
    		<sec:intercept-url pattern="/stream/startclient" access="IS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_FULLY"/>
    		<sec:intercept-url pattern="/stream/polysys" access="IS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_FULLY"/>
    		
            <!--  anything else -->
    		<sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
    		
    		
    		<sec:form-login login-page="/acegilogin.jsp" authentication-failure-url="/acegilogin.jsp?login_error=1"/>
    		<sec:anonymous />
    		<sec:http-basic />
    		<sec:remember-me />
    	</sec:http>
    
    	<bean class="org.springframework.security.ui.logout.LogoutFilter">
    		<sec:custom-filter position="LOGOUT_FILTER"/>
    	
    	    <constructor-arg value="/acegilogin.jsp"/> <!-- URL redirected to after logout -->
    	    <constructor-arg>
    	            <list>
    	            		<ref local="updateLogoutDateHandler"/>
    	                    <ref local="logoutHandler"/>
    	            </list>
    		</constructor-arg>
    		<property name="filterProcessesUrl" value="/logout.jsp"/>
        </bean>
        
        <bean id="logoutHandler" class="org.springframework.security.ui.logout.SecurityContextLogoutHandler"/>
        
        <bean class="org.springframework.security.concurrent.ConcurrentSessionFilter" autowire="autodetect">
        	<sec:custom-filter position="CONCURRENT_SESSION_FILTER"/>
        	<property name="sessionRegistry" ref="sessionRegistry"/>
        	<property name="logoutHandlers">
        		<list>
        			<ref local="logoutHandler"/>
        		</list>
        	</property>
        </bean>
        
        <bean id="concurrentSessionController" class="org.springframework.security.concurrent.ConcurrentSessionControllerImpl">
    		<property name="maximumSessions"><value>1</value></property>
    		<property name="sessionRegistry"><ref local="sessionRegistry"/></property>
    	</bean>
        
        <!--bean id="sessionRegistry" class="com.synergon.syrius.security.ClusterSessionRegistry"/-->
        <bean id="sessionRegistry" class="org.springframework.security.concurrent.SessionRegistryImpl"/>
        
        <bean id="updateLogoutDateHandler" class="com.synergon.syrius.security.UpdateLogoutDateHandler" autowire="autodetect"/>
    	
    	<bean class="org.springframework.security.intercept.method.aopalliance.MethodDefinitionSourceAdvisor" autowire="constructor"/>
    	
    	<bean class="org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor">
    		<property name="validateConfigAttributes"><value>false</value></property>
    		<property name="authenticationManager"><ref bean="authenticationManager"/></property>
    		<property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property>
    		<property name="objectDefinitionSource">
    	        <bean class="org.springframework.security.intercept.method.MethodDefinitionAttributes">
            		<property name="attributes">
    					<bean class="com.synergon.syrius.security.SyriusSecurityAnnotationAttributes"/>
    				</property>
             	</bean>
    		</property>
    	</bean>
    	
    	<bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
    		<property name="allowIfAllAbstainDecisions" value="false"/>
    		<property name="decisionVoters">
    			<list>
    				<bean class="org.springframework.security.vote.RoleVoter">
    					<property name="rolePrefix" value=""/>
    				</bean>
    				<bean class="org.springframework.security.vote.AuthenticatedVoter"/>
    			</list>
    		</property>
    	</bean>
    		
    	<!-- sec:global-method-security secured-annotations="enabled" access-decision-manager-ref="accessDecisionManager"/>-->
    	<sec:authentication-manager alias="authenticationManager"/>
    	
    	<sec:ldap-server id="ldapServer" url="ldap://syrius-dc1:389/DC=siriusad,DC=local" manager-dn="CN=Administrator,CN=Users,DC=siriusad,DC=local" manager-password="12345678"/>
    	<sec:ldap-user-service server-ref="ldapServer" user-search-filter="(sAMAccountName={0})" />
    
    	<bean class="com.synergon.syrius.security.SpringSecurityAuthenticationProvider" autowire="default">
    		<sec:custom-authentication-provider />
    
    		<constructor-arg ref="bindAuthenticator"/>
    		<constructor-arg>
    			<bean class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
    				<constructor-arg ref="ldapServer" />
    				<constructor-arg value="OU=Users,OU=TD" />
    				<property name="groupRoleAttribute" value="OU" />
    			</bean>
    		</constructor-arg>
    	</bean>
    	
    	<bean id="bindAuthenticator" class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
    		<constructor-arg ref="ldapServer" />
    		 <property name="userSearch">
    		 		<bean class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
    					<constructor-arg index="0">
    						<value>OU=Users,OU=TD</value>
    					</constructor-arg>
    					<constructor-arg index="1">
    						<value>(sAMAccountName={0})</value>
    					</constructor-arg>
    					<constructor-arg index="2">
    						<ref local="ldapServer"/>
    					</constructor-arg>
    					<property name="searchSubtree">
    						<value>true</value>
    					</property>
    				</bean>
    		 </property>
    	</bean>
    
    	
    	<bean id="felhasznaloLdapMapper" class="com.synergon.syrius.ad.FelhasznaloLdapMapper" autowire="autodetect"/>
    	<bean id="szervezetiEgysegLdapMapper" class="com.synergon.syrius.ad.SzervezetiEgysegLdapMapper" autowire="autodetect"/>
    	<bean id="activeDirectoryReplicator" class="com.synergon.syrius.ad.ActiveDirectoryReplicator" autowire="byName">
    		<property name="ldapBaseDN">
    			<value>DC=siriusad,DC=local</value>
    		</property>
    		<property name="ldapUsersBaseDN"><ref bean="ldapUsersBaseDN"/></property>
    		<property name="ldapSzervezetekBaseDN"><ref bean="ldapSzervezetekBaseDN"/></property>
    	</bean>
    
    	<bean id="felhasznaloLdapPopulator" class="com.synergon.syrius.security.FelhasznaloLdapPopulator" autowire="autodetect">
    		<property name="szervezetiEgysegekBaseDN">
    			<value>OU=Users,OU=TD</value>
    		</property>
    	</bean>
    </beans>
    According to the log files, the ConcurrentSessionFilter is configured at order 100 and is executing on every request. Still, I can log in from two boxes using the exact same user, without getting the first session invalidated.

    I'm using Spring Security 2.0.1. Any help or suggestions appreciated.

    Thanks,
    Kristof

  • #2
    Ok the problem root seems to be that my authenticationManager bean is using a NullConcurrentSessionController instead of my concurrentSessionController bean.

    I tried to replace this piece of configuration:
    Code:
    <sec:authentication-manager alias="authenticationManager"/>
    with this:
    Code:
    <bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
    		<property name="sessionController">
    			<ref local="concurrentSessionController"/>
    		</property>
    		<property name="providers">
    			<list>
    				<ref local="springAuthenticationProvider"/>
    			</list>
    		</property>
    	</bean>
    but the situation remained the same: my authenticationManager bean is still using a NullConcurrentSessionController according to my debug.

    What am I missing here?

    Comment


    • #3
      This looks like the same issue that wa being discussed a couple of days ago

      http://forum.springframework.org/showthread.php?t=53742

      We need a better solution - possibly some way of setting either the ConcurrentSessionController or SessionRegistry.

      Comment


      • #4
        Ok, I've read that thread but still failed to get it. My self-configured authenticationManager bean is not used, being shadowed by a default one configured because I use the <http/> tag, that's what happening here? (I don't get any startup exceptions because of duplicate authenticationManagers).

        That means that I should get rid of the whole <http/> tag and configure everything in it manually? Can I know *anyhow* exactly what's being autoconfigured and what bean definitions will be used when I use any namespace tags? Is there a documentation somewhere about this?

        Most importantly, how should I configure then ConcurrentSessionFilter with a cluster-aware SessionRegistry (I wrote one which I believe will work correctly) with Spring Security 2.0.x?

        Thanks for your assistance.

        Comment


        • #5
          if you use spring security 2.0.1 instead of 2.0.0, you will get duplicated authenticationManager error. it seems at present the only way to use customised concurrent session control is to manually define springSecurityFilterChain instead of using <security:http/> tag. example below:
          Code:
          	<bean id="springSecurityFilterChain" class="org.springframework.security.util.FilterChainProxy">
          		<security:filter-chain-map path-type="ant">
          	    	<security:filter-chain pattern="/website/customer/**" filters="concurrentSessionFilter,httpSessionContextIntegrationFilter,website.exceptionTranslationFilter,filterInvocationInterceptor"/>
          	    	<security:filter-chain pattern="/restaurant/**" filters="httpSessionContextIntegrationFilter"/>
          	  	</security:filter-chain-map>
          	</bean>
          	<!-- ===================== assistant FILTERS ==================== -->
          	<bean id="httpSessionContextIntegrationFilter" class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>
          	<!-- ======================== Concurrent Session Filter ======================= -->
           	<bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
          		<property name="providers">
          			<list>
          				<ref local="operatorAuthenticationProvider"/>
          				<ref local="customerAuthenticationProvider"/>
          			</list>
          		</property>
          		<property name="sessionController" ref="concurrentSessionController"/>
          	</bean>
              <bean id="concurrentSessionFilter" class="org.springframework.security.concurrent.ConcurrentSessionFilter">
                  <property name="expiredUrl" value="/Login.jsf"/>
                  <property name="sessionRegistry"><ref local="sessionRegistry"/></property>
              </bean>
              <bean id="concurrentSessionController" class="org.springframework.security.concurrent.ConcurrentSessionControllerImpl">
          		<property name="maximumSessions" value="1"/>
          		<property name="sessionRegistry"><ref local="sessionRegistry"/></property>
          	</bean>
          	<bean id="sessionRegistry" class="org.springframework.security.concurrent.SessionRegistryImpl"/>
          Cheng

          Comment


          • #6
            Cheng,

            I can double it, I'm using spring security 2.0.1 with a <http/> tag and a self-configured authenticationManager and I'm not getting any duplicate bean definition exceptions at all.

            You say I'm better off porting my Acegi 1.5 config and starting from scratch?

            Comment


            • #7
              hi dyn, that is very strange that you didn't get duplicated bean exception, as the source code in 2.0.1 prevents you from defining more than one FilterChainProxy with code below:
              Code:
              class org.springframework.security.config.HttpSecurityBeanDefinitionParser
              {
                  ...
                  /*line 192*/
                  private void registerFilterChainProxy(ParserContext pc, Map filterChainMap, UrlMatcher matcher, Object source) {
                      if (pc.getRegistry().containsBeanDefinition(BeanIds.FILTER_CHAIN_PROXY)) {
                          pc.getReaderContext().error("Duplicate <http> element detected", source);
                      }
                  ...
                }
                ...
              }
              i am not very certain, but i did get duplicated bean exception.

              yes, in my case, the configuration with acegi 2.0.x is not simplified much comparing to use acegi 1.0.x, as i have many customised requirements.

              Comment


              • #8
                That is a check on the bean name - it will prevent you having two <http> blocks. You should be able to configure independent FilterChainProxy instances though and map them to whatever URLs you want in your web.xml. Using the standard name "springSecurityFilterChain" for your bean is probably not a good idea since anyone seeing that will probably assume you are using the namespace version.

                Comment


                • #9
                  Ok. Can anyone please tell me how to translate this block into non-namespace configuration:

                  Code:
                  <sec:http access-decision-manager-ref="accessDecisionManager">
                  		<sec:intercept-url pattern="/images/*" access="IS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_FULLY"/>
                      	<sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
                  		
                  		<sec:form-login login-page="/acegilogin.jsp" authentication-failure-url="/acegilogin.jsp?login_error=1"/>
                  		<sec:anonymous />
                  		<sec:http-basic />
                  	</sec:http>
                  so everything which gets automagically included here will be included into my new non-namespace config? I think I can deal with the rest once I get through this...

                  Comment


                  • #10
                    http://jira.springframework.org/browse/SEC-821

                    Comment


                    • #11
                      Any chance to help me rewriting this <sec:http/> block with non-namespace based configuration? It aint seem *that* long for me..


                      Originally posted by dyn View Post
                      Code:
                      <sec:http access-decision-manager-ref="accessDecisionManager">
                      		<sec:intercept-url pattern="/images/*" access="IS_AUTHENTICATED_ANONYMOUSLY,IS_AUTHENTICATED_FULLY"/>
                          	<sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
                      		
                      		<sec:form-login login-page="/acegilogin.jsp" authentication-failure-url="/acegilogin.jsp?login_error=1"/>
                      		<sec:anonymous />
                      		<sec:http-basic />
                      	</sec:http>

                      Comment


                      • #12
                        So I seem to have this issue, but the strange thing is, when I run Maven:cargo to deploy to embedded Tomcat and then access the application, the security works fine. But when I run through TestNG ->cargo ->tomcat, I keep getting this error:

                        Code:
                        Offending resource: class path resource [applicationContext-test.xml]; nested exception is org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Duplicate <global-method-security> detected.
                        Offending resource: file [C:\opt\projects\baselogic\common-services\webapp-services\web\target\test-classes\WEB-INF\applicationContext-security.xml]
                            at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)
                        NOTE: When I remove the <global-method-security> section, I get the same error for <http> which is the issue in this thread.

                        Here is my security applicationContext:
                        [code]<?xml version="1.0" encoding="UTF-8"?>

                        <!--
                        - Sample namespace-based configuration
                        -
                        -->
                        <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.5.xsd
                        http://www.springframework.org/schema/security
                        http://www.springframework.org/schema/security/spring-security-2.0.2.xsd">

                        <global-method-security secured-annotations="enabled">
                        <!-- AspectJ pointcut expression that locates our "post" method and applies security that way
                        <protect-pointcut expression="execution(* bigbank.*Service.post*(..))" access="ROLE_USER"/>

                        -->
                        </global-method-security>

                        <http auto-config="true" access-denied-page="/view/error/403.jsp">
                        <intercept-url pattern="/login.jsp*" filters="none"/>

                        <intercept-url pattern="/view/admin/**" access="ROLE_ADMIN"/>
                        <intercept-url pattern="/view/member/**" access="ROLE_USER,ROLE_ADMIN"/>


                        <!-- All of this is unnecessary if auto-config="true" -->
                        <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp" default-target-url="/person.jsp" />

                        <!--anonymous /-->

                        <!--http-basic / -->

                        <logout logout-success-url="/index.html"/>

                        <!--remember-me /-->

                        <!--servlet-api-integration /-->

                        <concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/>

                        </http>


                        <authentication-provider>
                        <jdbc-user-service data-source-ref="dataSource"
                        users-by-username-query="SELECT username, password, 'true' FROM app_user WHERE username=?"
                        authorities-by-username-query="SELECT username, role.name as authority FROM app_user, role, user_role WHERE user_role.user_id = app_user.id AND app_user.username = ?"/>
                        </authentication-provider>

                        </beans:beans>

                        Comment


                        • #13
                          Got simular errors.

                          Reason was that the jar's needed were not in place and wrong versions....

                          Comment


                          • #14
                            Case solved:

                            the needed jar's were not in place after deploy in the \WEB-INF\lib

                            Comment


                            • #15
                              That was not the issue. But I did solve the issue:

                              First off, when I was using acegi, I declared an applicationContext-test.xml that myTestNG would instanciate. I then would import my other applicationContext*.xml's that I thought I would need. Now this did not cause an issue in acegi:
                              <import resource="classpath:applicationContext-service.xml"/>
                              <import resource="classpath:/WEB-INF/applicationContext*.xml"/> But when I moved to Spring Security 2.0.2, I started getting this error:
                              Offending resource: class path resource [applicationContext-test.xml];
                              nested exception is org.springframework.beans.factory.parsing.BeanDefi nitionParsingException:
                              Configuration problem: Duplicate <global-method-security> detected.
                              Offending resource:
                              file [C:\opt\projects\baselogic\common-services\webapp-services\web\target\test-classes\WEB-INF\applicationContext-security.xml]
                              at org.springframework.beans.factory.parsing.FailFast ProblemReporter.error(FailFastProblemReporter.java :68) When I removed the <global-method-security> I got the same error in the <http> section just as the spring thread above.
                              The thing that helped me to solve this, and was a strange indicator, was that when I ran this stand alone "mvn -Dcargo.wait=true cargo:start" or "mvn tomcat:run-war" the application would start, and function as expected. So I was confused as everything worked before Spring Security, but now it does not.
                              The issue seems to be that if maven is deploying the application to embedded tomcat, then TestNG is starting the applicationContext-test.xml which in turn was importing classpath:/WEB-INF/applicationContext*.xml which is the same import as my web.xml is importing:
                              <context-param>
                              <param-name>contextConfigLocation</param-name>
                              <param-value>
                              /WEB-INF/applicationContext*.xml
                              </param-value>
                              </context-param> The strange thing is, only my Spring Security has the issue. All my other beans start just fine. So as soon as I removed that declaration from my applicationContext-test.xml for TestNG Testing, the error was fixed.

                              Comment

                              Working...
                              X