`
hanqunfeng
  • 浏览: 1526312 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

SpringSecurity3.X--Cas client 配置之配置session-management遇到的问题

阅读更多

关于“SpringSecurity3.X--Cas client 配置”可以参看SpringSecurity3.X--Cas client 配置

 

直接说问题吧,就是希望同一时间相同的用户只能有一个访问系统,我理所当然的想到了session-management,在使用SpringSecurity2.x时,直接配置如下即可:

 <sec:http entry-point-ref="casProcessingFilterEntryPoint" 
    	access-denied-page="/access/denied.do" 
    	access-decision-manager-ref="accessDecisionManager" auto-config="false">
       …………………………
     <sec:concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="false" expired-url="/access/same_login.do" />
 </sec:http>

 也就是说,相同的用户在第二次登录后,那么第一次登录就会失效,需要重新获取认证。

 

在使用SpringSecurity3.X时,我尝试配置如下:

<http entry-point-ref="casEntryPoint" access-decision-manager-ref="accessDecisionManager"
		access-denied-page="/access/denied.do" auto-config="false">
                 …………………………

              <session-management> 
                     <concurrency-control max-sessions="1" expired-url="/access/same_login.do" 
			       error-if-maximum-exceeded="false" /> 
              </session-management> 
		
		<custom-filter position="CAS_FILTER" ref="casFilter" />
		<custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER" />
		<custom-filter ref="singleLogoutFilter" before="CAS_FILTER" />
</http>

 结果发现并没有起作用,查看了一下源码,基本上搞清楚了原因,下面是session管理相关的时序图:

从图中可以看出,验证的关键就是ConcurrentSessionControlStrategy

 

CasAuthenticationFilter继承于AbstractAuthenticationProcessingFilter,可是后者默认使用的不是ConcurrentSessionControlStrategy,而是NullAuthenticatedSessionStrategy,该类什么都没做,所以,上面的配置根本不会起作用,

那么要想使session-management真正起作用,我们该如何做呢?

 

首先,必须为CasAuthenticationFilter注入一个ConcurrentSessionControlStrategy,

然后,ConcurrentSessionControlStrategy和ConcurrentSessionFilter又需要使用相同的SessionRegistryImpl,所以我们只需要将这些bean显示声明即可。

参看了一下SpringSecurity3.X的官方帮助文件,修改配置如下:

<http entry-point-ref="casEntryPoint" access-decision-manager-ref="accessDecisionManager"
		access-denied-page="/access/denied.do" auto-config="false">
		…………………………
		<session-management
			session-authentication-strategy-ref="sessionAuthenticationStrategy" />
		<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
		<custom-filter position="CAS_FILTER" ref="casFilter" />
		<custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER" />
		<custom-filter ref="singleLogoutFilter" before="CAS_FILTER" />
	</http>


	<beans:bean id="sessionAuthenticationStrategy"
		class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
		<beans:constructor-arg name="sessionRegistry"
			ref="sessionRegistry" />
		<beans:property name="maximumSessions" value="1" />
	</beans:bean>

	<beans:bean id="sessionRegistry"
		class="org.springframework.security.core.session.SessionRegistryImpl" />
		
		
	<beans:bean id="concurrencyFilter"
		class="org.springframework.security.web.session.ConcurrentSessionFilter">
		<beans:property name="sessionRegistry" ref="sessionRegistry" />
		<beans:property name="expiredUrl" value="/session-expired.htm" />
	</beans:bean>


	<!-- cas 认证过滤器 -->
	<beans:bean id="casFilter"
		class="org.springframework.security.cas.web.CasAuthenticationFilter">
		<beans:property name="authenticationManager" ref="authenticationManager" />
		<beans:property name="authenticationFailureHandler"
			ref="authenticationFailureHandler" />
		<beans:property name="authenticationSuccessHandler"
			ref="authenticationSuccessHandler" />
		<beans:property name="filterProcessesUrl" value="/j_spring_cas_security_check.do" />
		<beans:property name="sessionAuthenticationStrategy"
			ref="sessionAuthenticationStrategy" />
	</beans:bean>
 

 

ok。

  • 大小: 59.3 KB
分享到:
评论
2 楼 renyuchuan 2014-07-08  
你好,按照你的做法,我修改了我的配置文件,我使用的是srping3.1,但现在还是可以在多个客户端使用相同账号登陆,也不影响另一个。我的配置文件如下:
<?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-3.1.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
	
	<!-- 此标签会创建第二种方式中的大多数bean,可配置的选项很多,可以自行查阅 -->
    <http auto-config="false" entry-point-ref="casEntryPoint" use-expressions="true" access-denied-page="/errorPage/error403.jsp">
    	<intercept-url pattern="/**/*" access="isAuthenticated()" />
    	<anonymous enabled="false" />
    	
    	<session-management  
            session-authentication-strategy-ref="sessionAuthenticationStrategy" />  
        <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
        <!-- 无spring时,这些filter都会被定义在web.xml中 -->
        <custom-filter position="CAS_FILTER" ref="casFilter" />
<!--        <logout logout-url="/j_spring_security_logout" logout-success-url="${cas-server-url}/logout?service=${cas-service-url}"/>-->
        <custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/>
        <custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/>
		
	</http>
    
    <beans:bean id="sessionAuthenticationStrategy"  
        class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">  
        <beans:constructor-arg name="sessionRegistry"  
            ref="sessionRegistry" />  
        <beans:property name="maximumSessions" value="1" />  
    </beans:bean>
	
	<beans:bean id="sessionRegistry"  
        class="org.springframework.security.core.session.SessionRegistryImpl" />  
          
    <beans:bean id="concurrencyFilter"  
        class="org.springframework.security.web.session.ConcurrentSessionFilter">  
        <beans:property name="sessionRegistry" ref="sessionRegistry" />  
        <beans:property name="expiredUrl" value="/j_spring_cas_security_logout" />  
    </beans:bean>
    
	<beans:bean id="serviceProperties"
          class="org.springframework.security.cas.ServiceProperties">
        <!-- 回调访问的url -->
        <beans:property name="service" value="${cas-service-url}/j_spring_cas_security_check"/>
        <!-- 根据需要启用此参数,当url传递renew参数并且为true时,无论用户有无认证cookie都会强制进行验证 -->
        <beans:property name="sendRenew" value="false"/>
    </beans:bean>

    <beans:bean id="casFilter"
          class="org.springframework.security.cas.web.CasAuthenticationFilter">
        <beans:property name="authenticationManager" ref="authenticationManager"/>
        <beans:property name="authenticationFailureHandler"  
            ref="authenticationFailureHandler" />  
        <beans:property name="authenticationSuccessHandler"  
            ref="authenticationSuccessHandler" />  
        <beans:property name="filterProcessesUrl" value="/j_spring_cas_security_check" />  
        <beans:property name="sessionAuthenticationStrategy"  
            ref="sessionAuthenticationStrategy" />
    </beans:bean>
    
    <!-- cas 认证失败控制器 -->  
    <beans:bean id="authenticationFailureHandler"  
        class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">  
        <beans:property name="defaultFailureUrl" value="/common/timeout.jsp" />  
    </beans:bean>  
    <!-- cas 认证成功控制器 -->  
    <beans:bean id="authenticationSuccessHandler"  
        class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">  
        <beans:property name="alwaysUseDefaultTargetUrl" value="false" />  
<!--        <beans:property name="defaultTargetUrl" value="/index.jsp" />  -->
    </beans:bean>  

    <beans:bean id="casEntryPoint"
          class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
        <beans:property name="loginUrl" value="${cas-server-url}/login"/>
        <beans:property name="serviceProperties" ref="serviceProperties"/>
    </beans:bean>

    <authentication-manager alias="authenticationManager">
        <authentication-provider ref="casAuthenticationProvider" />
    </authentication-manager>

    <beans:bean id="casAuthenticationProvider"
          class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
        <beans:property name="authenticationUserDetailsService">
            <beans:bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
                <beans:constructor-arg ref="loginServiceImpl" />
            </beans:bean>
        </beans:property>
        <beans:property name="serviceProperties" ref="serviceProperties" />
        <beans:property name="ticketValidator">
            <beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
                <beans:constructor-arg index="0" value="${cas-server-url}" />
            </beans:bean>
        </beans:property>
        <beans:property name="key" value="an_id_for_this_auth_provider_only"/>
    </beans:bean>
    <beans:bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>

    <beans:bean id="requestSingleLogoutFilter"
          class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <beans:constructor-arg value="${cas-server-url}/logout"/>
        <beans:constructor-arg>
            <beans:bean class=
                          "org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
        </beans:constructor-arg>
        <beans:property name="filterProcessesUrl" value="/j_spring_cas_security_logout"/>
    </beans:bean>
</beans:beans>    
1 楼 lovefly_zero 2012-07-13  
我运用了你的session-management,但是我有多个不同的子系统,导致我注销时不能同时注销其它子系统,何解?

相关推荐

Global site tag (gtag.js) - Google Analytics