我正在使用Spring Security开发Grails Web应用程序。我有一个要求,即使会话处于活动状态,也必须在固定的时间后强制会话过期。
我想我可以添加过滤器并检查每个请求的上次登录时间:
if (CURRENT_TIME - LAST_LOGIN > ABSOLUTE_SESSIO EXPIRATION) then FORCE LOGOUT
但是问题在于,直到用户发出请求,会话仍在服务器上处于活动状态。
即使用户正在使用系统,这是否有可能在N分钟后立即破坏会话?我正在研究tomcat会话管理以及spring security如何处理它,但没有找到任何有用的信息。
有人可以指出我的例子吗?有人实施过类似的方法吗?
[编辑:在特定时间由登录时间决定终止会话的想法是使用任务调度程序(如Quartz)来调度通过会话作为参数传递的任务。然后,您可以计划它以调用session.invalidate()在特定时间点执行的作业。该任务将在登录时安排。]
session.invalidate()
这就是我要做的,但是并不会在您想要的特定时间终止会话。它依赖于用户发出请求。这不是万无一失的方法,但是您可以让应用程序每分钟左右通过AJAX调用来轮询站点。
在用户会话上设置会话激活时间。然后为所有传入的请求添加一个筛选器到Web应用程序,以检查(激活时间+允许的时间)是否超过当前时间。如果不是,则调用session.invalidate();。
即登录
HttpSession session = request.getSession(); session.setAttribute( "activation-time", System.currentTimeMillis() );
然后将过滤器添加到web.xml
<filter> <filter-name>SessionFilter</filter-name> <filter-class>com.something.SessionFilter</filter-class> <init-param> <param-name>max-period</param-name> <param-value>60000</param-value> </init-param> </filter> <filter-mapping> <filter-name>SessionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
过滤器将类似于…
package com.something; import java.io.IOException; import java.util.Date; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; public class SessionFilter implements Filter { private long maxPeriod; public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpSession session = request.getSession( false ); if ( session != null ) { long activated = (long) session.getAttribute( "activation-time" ); if ( System.currentTimeMillis() > ( activated + maxPeriod ) ) { session.invalidate(); } } chain.doFilter(req, res); } public void init(FilterConfig config) throws ServletException { //Get init parameter if ( config.getInitParameter("max-period") == null ) { throw new IllegalStateException( "max-period must be provided" ); } maxPeriod = new Long( config.getInitParameter("max-period") ); } public void destroy() { //add code to release any resource } }
如果在会话无效时需要调用某些内容,则可以HttpSessionListener在web.xml中编写和配置。
HttpSessionListener