package com.ailk.biapp.ci.localization.cntv.filter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map; import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import net.sf.json.JSONObject; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.springframework.http.HttpStatus;
import org.springframework.web.filter.OncePerRequestFilter; import com.ailk.biapp.ci.localization.cntv.model.UserMessage;
import com.ailk.biapp.ci.util.JsonUtil;
import com.ailk.biapp.ci.util.RedisUtils;
import com.asiainfo.biframe.privilege.IUserSession;
import com.asiainfo.biframe.utils.config.Configure; public class sessionFilter extends OncePerRequestFilter{ // 登录页面
private String LoginPage = Configure.getInstance().getProperty("com.zyzx.dmc.login.html"); @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
HttpServletRequest hrequest = (HttpServletRequest) request;
HttpSession session = hrequest.getSession();
// 不过滤的uri
String[] notFilter = new String[] { "login.html", ".js", "/css","/images", "/logout", "/druid", "/login","/ssoAuth" }; // 请求的uri
String url = request.getRequestURL().toString();
//Token String token = request.getParameter("token");
// String url = uri.replaceAll("html", "bak");
// 是否过滤
boolean doFilter = true;
for (String s : notFilter) {
if (url.indexOf(s) != -1) {
// 如果uri中包含不过滤的uri,则不进行过滤
doFilter = false;
break;
}
} /*
* if(uri.contains("jsp") && uri.indexOf("login.jsp") == -1) { doFilter
* = true; }
*/
if (doFilter) {
// 执行过滤
// 从session中获取登录者实体
Object user = request.getSession().getAttribute(IUserSession.ASIA_SESSION_NAME);
final IUserSession userSession = (IUserSession) session.getAttribute(IUserSession.ASIA_SESSION_NAME);
final UserMessage UserMessage = (UserMessage) session.getAttribute("TOKEN"); if (UserMessage == null) {
//未登录状态
if(null == token){
response.sendRedirect(LoginPage + "?goto=" + url);
return;
//token 存在则去保存session,验证用户信息
}else{
JSONObject result = checkTokenInfo(token);
if(null == result){
response.sendRedirect(LoginPage + "?goto=" + url);
return;
}
//验证成功
if("suc".equals(result.get("result"))){
//正常登录
Map<String,String> sessionUserInfo = new HashMap<String, String>();
UserMessage userMessage = new UserMessage();
sessionUserInfo = JsonUtil.json2HashMap(result.get("userInfo").toString());
sessionUserInfo.put("token", token); String ip = request.getHeader("x-forwarded-for");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
userMessage.setUserID(sessionUserInfo.get("user_account"));
userMessage.setUserName(sessionUserInfo.get("user_name"));
userMessage.setSessionID(sessionUserInfo.get("token"));
userMessage.setClientIP(ip);
userMessage.setToken(sessionUserInfo.get("token"));
request.getSession().setAttribute(IUserSession.ASIA_SESSION_NAME,userMessage);
request.getSession().setAttribute("TOKEN",userMessage);
response.sendRedirect(url);
}else if("fail".equals(result.get("result"))){
response.sendRedirect(LoginPage + "?goto=" + url);
}
}
// 如果session中不存在登录者实体,则弹出框提示重新登录
boolean isAjaxRequest = isAjaxRequest(request);
if (isAjaxRequest) {
// 设置request和response的字符集,防止乱码
response.setContentType("text/html;charset=UTF-8");
response.sendError(HttpStatus.UNAUTHORIZED.value(), "您已经太长时间没有操作,请刷新页面");
return;
}
}else {
token = UserMessage.getToken();
String booleanexist = RedisUtils.getForString(token);
if(booleanexist == null){
session.removeAttribute("TOKEN");
session.removeAttribute(IUserSession.ASIA_SESSION_NAME);
response.sendRedirect(LoginPage + "?goto=" + url);
return;
}
// 如果session中存在登录者实体,则继续
filterChain.doFilter(request, response);
}
} else {
// 如果不执行过滤,则继续
filterChain.doFilter(request, response);
}
} /**
* 判断是否为Ajax请求 <功能详细描述>
*
* @param request
* @return 是true, 否false
* @see [类、类#方法、类#成员]
*/
public static boolean isAjaxRequest(HttpServletRequest request) {
String header = request.getHeader("X-Requested-With");
if (header != null && "XMLHttpRequest".equals(header))
return true;
else
return false;
}
/**
*
* 验证Token是否存在
* @param tokenValue
* @return
* @throws IOException
*/
private JSONObject checkTokenInfo(String tokenValue) throws IOException {
String checkUrl = Configure.getInstance().getProperty("com.zyzx.aqs.tokenCheckUrl")+tokenValue;
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod(checkUrl);
try {
httpclient.executeMethod(httpget);
String result = httpget.getResponseBodyAsString();
JSONObject json = JSONObject.fromObject(result);
return json;
} finally {
httpget.releaseConnection();
}
} }

其实可以直接用userSession 但由于项目已经封装了,所以再创建个UserMessage实体类,在登录后将token存入session,当从redis中通过key获取token为空时,便清除userSession,跳转到指定系统页面。

单点登录filter根据redis中的key判断是否退出的更多相关文章

  1. 如何解决Redis中的key过期问题

    最近我们在Redis集群中发现了一个有趣的问题.在花费大量时间进行调试和测试后,通过更改key过期,我们可以将某些集群中的Redis内存使用量减少25%. Twitter内部运行着多个缓存服务.其中一 ...

  2. 超大批量删除redis中无用key+配置

    目前线上一个单实例redis中无用的key太多,决定删除一部分. 1.删除指定用户的key,使用redis的pipeline 根据一定条件把需要删除的用户统计出来,放到一个表里面,表为 del_use ...

  3. 单点登录在asp.net中的简单实现

    系统的基本架构 我们假设一个系统System包含Service客户服务中心.Shop网上购物中心和Office网上办公中心三个独立的网站.Service管理客户的资料,登录和注销过程.不论客户访问Sy ...

  4. Python查询Redis中的Key

    今日,大哥让我查下项目的在线用户量,听到这个消息顿时懵逼了,在线用户量,这个该怎么查????想到项目中的登陆用户缓存信息Token都存放在Redis中,是不是可以根据Redis中Token的个数大致估 ...

  5. redis中的key设置过期时间

    EXPIRE key seconds 为给定  key  设置生存时间,当  key  过期时(生存时间为  0  ),它会被自动删除. 在 Redis 中,带有生存时间的  key  被称为『易失的 ...

  6. Redis中对Key进行分类

    使用":"体现层次 >set key1:key2:key4 value1 "OK" >set key1:key2:key5 value2 " ...

  7. 转载文章(Redis中对key的操作)

    转载地址:http://www.cnblogs.com/stephen-liu74/archive/2012/03/26/2356951.html 一.概述: 在该系列的前几篇博客中,主要讲述的是与R ...

  8. redis中与key相关的命令

    1.简单描述 redis本质上是一个key-value db,value可以有多种类型(string.hash.set.sorted set.list等),本章节不讲这些类型的命令,这里是讲跟key相 ...

  9. 【转】批量删除redis中的key

    1. DEL 直接加键名称 DEL key1 key2 key3 127.0.0.1:6379>  DEL site_msg_99973  false site_msg_99974   fals ...

随机推荐

  1. UVa 103 Stacking Boxes --- DAG上的动态规划

    UVa 103 题目大意:给定n个箱子,每个箱子有m个维度, 一个箱子可以嵌套在另一个箱子中当且仅当该箱子的所有的维度大小全部小于另一个箱子的相应维度, (注意箱子可以旋转,即箱子维度可以互换),求最 ...

  2. ChannelOption.TCP_NODELAY, true->浅谈tcp_nodelay的作用

    在TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认.为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据.这里就涉及到一个名 ...

  3. 使用Cloudera部署,管理Hadoop集群

    Hadoop系列之(三):使用Cloudera部署,管理Hadoop集群 http://www.cnblogs.com/ee900222/p/hadoop_3.html Hadoop系列之(一):Ha ...

  4. dedecms的特性-----不完整

    1.前后台分离彻底,连模板引擎都不同 2.多入口,但使用相同的基类--------每个入口都清晰

  5. lucene 索引合并策略

    在索引算法确定的情况下,最为影响Lucene索引速度有三个参数--IndexWriter中的 MergeFactor, MaxMergeDocs, RAMBufferSizeMB .这些参数无非是控制 ...

  6. SVG添加链接(转载)

    转载地址:http://tech.techweb.com.cn/thread-258715-1-1.html 最基本的交互形式是链接.在 SVG 中,通过一个 <a> 标签提供链接,这与 ...

  7. 028. asp.net数据绑定控件值DataList控件

    DataList控件可以使用模板与定义样式来显示数据并进行数据的选择, 删除及编辑工作. DataList控件的最大特点是一定要通过模板来定义数据的显示格式. 如果要设计出美观的界面, 就需要花费一番 ...

  8. 【转】用ASP.NET加密Cookie数据

    来源:http://www.cnblogs.com/taizhouxiaoba/archive/2009/02/05/1384772.html Cookie中的数据以文本的形式存在客户端计算机,考虑它 ...

  9. The repository for high quality TypeScript type definitions

    Best practices This is a guide to the best practices to follow when creating typing files. There are ...

  10. form表单元素类型

    <form> <input type="text"> <input type="password"> <input t ...