import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.csair.amp.web.webinf.common.model.LoginInfo;
/**
* 用户登陆验证过滤器
*
* @author ahomeeye
*
* 2012-6-01
*
*/
public class SSOFilter implements Filter {
private Log log = LogFactory.getLog(SSOFilter.class);
private String loginUrl;//登录后跳转到的URL
private String redirectPath;//登录URL
//不过滤的URL
private List<String> noFiltList = new ArrayList<String>();
//不过滤的后缀
private List<String> skipSuffixList = new ArrayList<String>();
/**
* 创建一个用户登陆验证过滤器对象,一般由容器调用
*/
public SSOFilter() {
super();
}
/**
* 过滤器销毁,由容器调用 空实现
*/
public void destroy() {
}
/**
* 用户登录过滤,由容器调用
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession session = req.getSession();
// 清除页面缓存
res.setHeader("Pragma", "no-cache");
res.setHeader("Cache-Control", "no-cache");
res.setDateHeader("Expires", 0);
// 获取根路径
String path = req.getServletPath();
if (isInNoFiltList(path, this.noFiltList)
|| isInSkipList(path, this.skipSuffixList)) {
chain.doFilter(request, response);
return;
}
if (this.redirectPath.equalsIgnoreCase(path) || "/".equals(path)) {
if (authentication(session)) {
res.sendRedirect(this.loginUrl);
} else {
chain.doFilter(request, response);
return;
}
} else {
if (authentication(session) == false) {
// 权限受限,返回提示信息页面
String url = req.getContextPath() + this.redirectPath;
res.sendRedirect(url);
} else {
chain.doFilter(req, res);
}
}
}
/**
* 初始化方法,容器调用
*/
public void init(FilterConfig filterConfig) throws ServletException {
this.redirectPath = filterConfig.getInitParameter("redirectPath");
this.loginUrl = filterConfig.getInitParameter("loginPath");
String ignoreUrl = filterConfig.getInitParameter("ignoreUrl");
if (ignoreUrl != null) {
String[] no = ignoreUrl.split(",");
if (no != null && no.length > 0) {
for (String n : no) {
noFiltList.add(n);
}
}
}
String skipSuffix = filterConfig.getInitParameter("skipSuffixes");
if (skipSuffix != null) {
skipSuffix = skipSuffix.toLowerCase();
String[] skip = skipSuffix.split(",");
if (skip != null && skip.length > 0) {
for (String s : skip) {
skipSuffixList.add(s);
}
}
}
}
/**
* 判断路径是否跳过验证
* @param path 请求的资源路径
* @param list 跳过验证的后缀列表
* @return
*/
private boolean isInSkipList(String path, List<String> list) {
if (path == null || list == null) {
return false;
}
path = path.toLowerCase();
for (int i = 0; i < list.size(); i++) {
if (path.endsWith("." + list.get(i))) {
return true;
}
}
return false;
}
/**
* 判断特定的路径是否在跳过验证文件名列表中
* @param path 请求的资源路径
* @param list 跳过验证的文件名列表
* @return
*/
private boolean isInNoFiltList(String path, List<String> list) {
if (path == null || list == null) {
return false;
}
if (list.contains(path)) {
return true;
}
return false;
}
/**
* 认证用户登陆信息
*
* @param session
* 用户请求会话
* @return True/False 用户是否已经登录
*/
private boolean authentication(HttpSession session) {
LoginInfo user = (LoginInfo) session.getAttribute("user");
if (user != null) {
if (user.getUsername() == null || user.getUsername().equals("")) {
log.error("SSO invalid[Can not get username from session.]");
return false;
} else if (user.getPassword() == null
|| user.getPassword().equals("")) {
log.error("SSO invalid[Can not get password from session.]");
return false;
}
if (user.getUsername() != null && !user.getUsername().equals("")
&& user.getPassword() != null
&& !user.getPassword().equals("")) {// 用户名和密码非空
log.info("SSO success[User is valid.]");
return true;
}
} else {
log.error("SSO invalid[Can not get user from session.]");
}
return false;
}
}
LoginInfo是用户信息JavaBean,包含username和password两个属性。
web.xml添加内容:
<filter>
<filter-name>ssoFilter</filter-name>
<filter-class>com.csair.amp.web.webinf.fliters.SSOFilter</filter-class>
<init-param>
<param-name>ignoreUrl</param-name>
<param-value>/error.html,/limited.html,/login/security.inf,/security/login.inf</param-value>
</init-param>
<init-param>
<param-name>redirectPath</param-name>
<param-value>/index.html</param-value>
</init-param>
<init-param>
<param-name>loginPath</param-name>
<param-value>/main.html</param-value>
</init-param>
<init-param>
<param-name>skipSuffixes</param-name>
<param-value>pdf,jpg,png,txt,css,gif,js</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ssoFilter</filter-name>
<url-pattern>*.inf</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>/</url-pattern>
</filter-mapping>
html5的缓存配置文件为cache.manifest,该文件web在项目根目录下,添加内容:
//需要缓存的资源
CACHE:
views/index.html
//不要缓存的资源
NETWORK:
/index.html