package com.norteksoft.acs.web.filter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
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.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class SessionFailFilter implements Filter {
public static final int ADDITION_ACTIVE_TIME = 8*60*60;
private static final int FAIL_NUMBER = 3613; // 当session.getMaxInactiveInterval()时间为1小时13秒时,表示session已经失效
private static Log log = LogFactory.getLog(SessionFailFilter.class);
public void destroy() { }
public void doFilter(ServletRequest req, ServletResponse rep,
FilterChain chan) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) rep;
HttpSession session = request.getSession(false);
//这两个地址不用判断session过期
if(request.getRequestURI().contains("/j_spring_security_logout")||request.getRequestURI().contains("/exception-handle.action")){
if(StringUtils.isNotEmpty(request.getParameter("expired"))){
cleanCookie(request, response);
}
}else {
if (isSessionFailed(session)) {
session.setMaxInactiveInterval(FAIL_NUMBER);
//session.invalidate();
//cleanCookie(request, response);
//SecurityContextHolder.clearContext();
response.sendRedirect(request.getContextPath()+"/portal/exception-handle.action?type=403&sessionFail=yes");
return;//重定向后就不需要传递到其他filter了
}
}
chan.doFilter(req, rep);
}
//判断session超时
private boolean isSessionFailed(HttpSession session) {
boolean sessionFail=false;
/*
* session为null说明是第一次登陆(这时要出正常的登陆页面)或者是session超时后被回收了(这时要出403页面)
* 代码无法判断这两种情况
* 解决方案 创建session时设置session永不失效,通过这个filter来判断时间使session失效
*/
if(session==null){
sessionFail=false;
log.debug("session is null");
}else{
sessionFail = isSessionFail(session);
if(sessionFail) {
ExceededOnlineUserFilter.removeConcurrencyStorage(session);
}
}
return sessionFail;
}
public static boolean isSessionFail(HttpSession session){
if(session.getMaxInactiveInterval()==FAIL_NUMBER) return true;
int maxActiveTime = session.getMaxInactiveInterval() - ADDITION_ACTIVE_TIME;
log.debug("session Inactive Interval:[" + maxActiveTime + "]");
long lastAccessedTime = session.getLastAccessedTime();
Date currentTime = new Date();// 当前时间
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(lastAccessedTime));
cal.add(Calendar.SECOND, maxActiveTime);
Date failTime = cal.getTime();// 失效时间
return (maxActiveTime > 0 && currentTime.after(failTime))?true:false;
}
private void cleanCookie(HttpServletRequest request, HttpServletResponse response){
Cookie[] cookie = request.getCookies();
if (cookie != null) {
for (int i = 0; i < cookie.length; i++) {
cookie[i].setValue(null);
response.addCookie(cookie[i]);
}
}
}
public String dateFormat(Date date) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return df.format(date);
}
public void init(FilterConfig arg0) throws ServletException { }
}