使用 Spring Security 时,会话超时比预期的要快
Posted
技术标签:
【中文标题】使用 Spring Security 时,会话超时比预期的要快【英文标题】:Session gets timed out sooner than expected when using Spring Security 【发布时间】:2012-08-02 15:38:53 【问题描述】:我正在使用 Spring Security 3.1,但遇到了会话超时问题。 我在 web.xml 中设置了会话超时,如下所示:
<session-config>
<session-timeout>
45
</session-timeout>
</session-config>
所以会话应该在 45 分钟后过期。 但是我注意到会话在 2 分钟后 正好 过期!无论我是否在使用应用程序。 这些是我的 Spring Security bean:
<bean id="ConcurrentSessionFilterAdmin" class="org.springframework.security.web.session.ConcurrentSessionFilter">
<property name="sessionRegistry" ref="sessionRegistry"/>
<property name="logoutHandlers">
<list>
<ref bean = "logoutHandler"/>
</list>
</property>
<property name="expiredUrl" value="/admin/login.jsp?error=expiredURL"/>
</bean>
<bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" autowire="byType" />
<bean id="logoutHandler"
class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
</bean>
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name="securityContextRepository" ref="securityContextRepository"/>
</bean>
<bean id="securityContextRepository"
class="org.springframework.security.web.context.HttpSessionSecurityContextRepository">
<property name="allowSessionCreation" value="false" />
</bean>
<bean id="logoutFilterAdmin"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg value="/admin/login.jsp" />
<constructor-arg>
<list>
<ref bean="logoutHandler"/>
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/admin/j_spring_security_logout"></property>
</bean>
<bean id="usernamePasswordAuthenticationFilterAdmin"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="usernameParameter" value="j_username"/>
<property name="passwordParameter" value="j_password"/>
<property name="allowSessionCreation" value="false"/>
<property name="authenticationFailureHandler" ref="authenticationFailureHandlerAdmin"/>
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationSuccessHandler" ref="authenticationSuccessHandlerAdmin"/>
<property name="continueChainBeforeSuccessfulAuthentication" value="false"/>
<property name="filterProcessesUrl" value="/admin/j_spring_security_check"/>
<property name="sessionAuthenticationStrategy" ref="sessionAuthenticationStrategy"/>
</bean>
<bean id="authenticationFailureHandlerAdmin"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/admin/login.jsp?error=loginfailed" />
</bean>
<bean id="authenticationSuccessHandlerAdmin"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="requestCache" ref="requestCache"/>
<property name="defaultTargetUrl" value="/admin/index.html"/>
</bean>
<bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache"/>
<bean id="sessionAuthenticationStrategy"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<property name="maximumSessions" value="1" />
<property name="migrateSessionAttributes" value="true"/>
</bean>
<bean id="basicAuthenticationFilterAdmin"
class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
<property name="authenticationDetailsSource" ref="authenticationDetailsSource"/>
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<bean id="authenticationDetailsSource"
class="org.springframework.security.authentication.AuthenticationDetailsSourceImpl"/>
<bean id="requestCacheAwareFilter"
class="org.springframework.security.web.savedrequest.RequestCacheAwareFilter">
<constructor-arg ref="requestCache"/>
</bean>
<bean id="securityContextHolderAwareRequestFilter"
class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter">
<property name="rolePrefix" value="ROLE_"/>
</bean>
<bean id="anonymousAuthenticationFilter"
class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
<constructor-arg value="KEY"/>
</bean>
<bean id="sessionManagementFilterAdmin" class="org.springframework.security.web.session.SessionManagementFilter">
<constructor-arg ref="securityContextRepository"/>
<constructor-arg ref="sessionAuthenticationStrategy"/>
<property name="authenticationFailureHandler" ref="authenticationFailureHandlerAdmin"/>
<property name="invalidSessionStrategy" ref="invalidSessionStrategyAdmin"/>
</bean>
<bean id="invalidSessionStrategyAdmin"
class="org.springframework.security.web.session.SimpleRedirectInvalidSessionStrategy">
<constructor-arg value="/admin/login.jsp"/>
<property name="createNewSession" value="false"/>
</bean>
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
<property name="accessDeniedHandler" ref="accessDeniedHandler" />
<property name="requestCache" ref="requestCache"/>
</bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint">
</bean>
<bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
</bean>
<bean id="filterSecurityInterceptorAdmin"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="securityMetadataSource" ref="myFilterInvocationSecurityMetadataSource" />
</bean>
<bean id="myFilterInvocationSecurityMetadataSource" class="com.datx.security.model.MyFilterSecurityMetadataSource" autowire="byName" scope="prototype">
</bean>
两分钟后,我被重定向到在第一个 bean 配置中设置的/admin/login.jsp?error=expiredURL
。 (这意味着会话已过期)
问题是这些 bean 中的哪一个负责会话过期?我没有设置什么属性导致了这个问题?
【问题讨论】:
我认为问题出在 invalidSessionStrategyAdmin bean 上。 你可以尝试将allowSessionCreation设置为true 以前做过。由于该应用程序完全基于 Restful Web 服务,如果我 [再次] 这样做,我会遇到更多麻烦,因为每个请求都会创建新会话,这会导致“每个请求都有一个登录页面”。 【参考方案1】:Spring Security 依赖于底层容器,即管理会话超时的容器(请添加有关您正在使用的容器的信息)。但是,我相信如果服务器与 Java EE 兼容,web.xml 设置通常应该具有更高的优先级。
还可以通过调用HttpSession.setMaxInactiveInterval() 方法动态调整单个会话超时,或者可以通过调用invalidate() 使会话无效。
在某些情况下,Spring Security 有可能使 session 失效(例如,在登录后,用户会获得一个新的 HttpSession)。
Spring Security 并发会话控制机制也可能导致会话失效,例如,如果指定了 max-sessions 值。
您可以通过为 org.springframework.security.* 命名空间设置 DEBUG 日志记录级别来检查 Spring Security 何时使会话无效,因为 Spring 通常会将此类信息写入记录器.
【讨论】:
您能否向我解释一下如何启用此调试日志。一个简短的提示可能就足够了。 请参阅reference 的第 1.3.2 节,例如,如果您使用 logback,它将是以上是关于使用 Spring Security 时,会话超时比预期的要快的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Security Adapter 时的 Keycloak 会话超时行为
使用 Spring Security saml 的 IDP 会话超时