实现思路

1.一个类,类中维护着一个已登录用户的map,每次登录取出上次该用户对应的session;并给session添加一个过期的属性标识lastHttpSession.setAttribute(BE_KICKED,"您的账号在另一地点登录,您被迫下线")

2.写一个sessionFilter,该sessionFilter取出每个request请求实例中维护的session,判断session中有没有BE_KICKEd

3.如果存在说明该session是被踢掉用户,返回给客户端被踢信息

废话不多说直接上代码

UserStatistiUtil

package com.gysoft.sso.utils;import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;import javax.servlet.http.HttpSession;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;/*** @author 周宁* @Date 2018-06-13 20:14*/
public class UserStatisticUtil {/*** 默认缓存2个小时*/public static final Integer DEFAULT_CACHE_SECONDS = 60*60*2;/*** 缓存容器的默认大小*/private static final Integer DEFAULT_SIZE = 10000;/*** 存放用户对应Session的map,用于踢出用户*/public static ConcurrentHashMap<String,HttpSession> userSessionMap = new ConcurrentHashMap();/*** 缓存容器,存放被踢下线的SessionId,如果一个被踢用户过了2小时去请求那么就是session超时而不是被踢*/private static final Cache<String, HttpSession> invalidSessionIdMap = CacheBuilder.newBuilder().maximumSize(DEFAULT_SIZE).expireAfterWrite(DEFAULT_CACHE_SECONDS, TimeUnit.SECONDS).build();/*** 判断是否是过期的sessionId* @param sessionId* @return*/public static boolean isInvalidSessionId(String sessionId){return getInvalidSessionId(sessionId)!=null;}/*** 取出已经过期的sessionId* @param key* @return Object*/public static HttpSession getInvalidSessionId(String key) {return invalidSessionIdMap.getIfPresent(key);}/*** 放入已经过期的sessionId* @param key* @param value*/public static void putInvalidSessionId(String key, HttpSession value) {invalidSessionIdMap.put(key, value);}}

CustomCas30ProxyReceivingTicketValidationFilter

public class CustomCas30ProxyReceivingTicketValidationFilter extends Cas30ProxyReceivingTicketValidationFilter {@Overrideprotected void onSuccessfulValidation(HttpServletRequest request, HttpServletResponse response, Assertion assertion) {String username =assertion.getPrincipal().getName();HttpSession lastHttpSession = UserStatisticUtil.userSessionMap.get(username);if(null!=lastHttpSession&&!UserStatisticUtil.isInvalidSessionId(lastHttpSession.getId())){try{lastHttpSession.setAttribute(BE_KICKED,"您的账号在另一地点登录,您被迫下线");}catch (IllegalStateException e){//TODO Nothing 出现这种情况的原因是浏览器的session过期了但是未被及时清除}}String dcpLoginInfo = (String) assertion.getPrincipal().getAttributes().get(DCP_LOGIN_INFO);HttpSession session = request.getSession();session.setAttribute(DCP_LOGIN_INFO,dcpLoginInfo);UserStatisticUtil.userSessionMap.put(username,session);}
}

SessionTimeOutFilter

package com.gysoft.sso.filter;import com.gysoft.sso.utils.UserStatisticUtil;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;import static com.gysoft.sso.bean.SessionVariable.BE_KICKED;
import static com.gysoft.sso.bean.SessionVariable.DCP_LOGIN_INFO;
import static com.gysoft.sso.utils.UserStatisticUtil.DEFAULT_CACHE_SECONDS;/*** session超时过滤* @author 周宁* @Date 2018-06-12 14:08*/
public class SessionTimeOutFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse res = (HttpServletResponse) response;HttpSession session = req.getSession();String queryString = req.getQueryString();//url地址需要单点认证,且session不存在,则需要验证地址是否包含ticketif(!CustomAuthenticationFilter.isRequestUrlExcluded(req)&&session.getAttribute(DCP_LOGIN_INFO)==null){if(queryString==null||queryString.indexOf("ticket")==-1){response.setContentType("application/json;charset=utf-8");response.getWriter().write("{\"msg\": \"用户未登录\",\"code\": " + 302 + ",\"result\":  "+null+"}");return;}}//在线互踢if(session.getAttribute(BE_KICKED)!=null){UserStatisticUtil.putInvalidSessionId(session.getId(),session,DEFAULT_CACHE_SECONDS);String msg = (String) session.getAttribute(BE_KICKED);session.invalidate();response.setContentType("application/json;charset=utf-8");response.getWriter().write("{\"msg\": "+msg+",\"code\": " + 302 + ",\"result\": " + null + "}");return;}chain.doFilter(req,res);}@Overridepublic void destroy() {}
}

Cas实现子系统登录互踢相关推荐

  1. SpringSecurity整合springBoot、redis——实现登录互踢

    背景 基于我的文章--<SpringSecurity整合springBoot.redis token动态url权限校验>.要实现的功能是要实现一个用户不可以同时在两台设备上登录,有两种思路 ...

  2. Spring Security OAuth2 实现登录互踢

    Spring Security OAuth2 实现登录互踢 工作中遇到的问题,通过网上查找资料,解决问题,记录一下,防止丢失. 1.重写DefaultTokenServices中的方法 ​ 自定义一个 ...

  3. 如何实现登录互踢 即如何实现当用户登录之后 如果在其他地方再次登录 则这边的用户自动退出系统...

    我先写一下基本思路,首先在用户数据库表里面加一个String token 然后 每次登录 随机生成一个六位数作为token, 分别存进数据库和session . 登录之后 在主界面写一个定时jq方法 ...

  4. Spring Security OAuth2 实现多人登录互踢下线

    点击上方蓝色字体,选择"标星公众号" 优质文章,第一时间送达 ▊ 老赵推荐(戳下方标题) 阿里大牛程序员的Java问题排查工具单 我已经不用 try catch 处理异常了!太烦人 ...

  5. springSecurity+jwt中实现互踢功能

    一.思路: 原来的实现用户登录态是: 1.后台登陆成功后生成一个令牌(uuid)----JwtAuthenticationSuccessHandler 2.后台把它包装成jwt数据,然后返回给前端-J ...

  6. 单用户登录记录互踢下线思路

    单用户登录记录(只谈redis实现) 用户登录成功生成随机值(uuid或者雪花算法,随意)存在redis(假设key="token-user:token",值="user ...

  7. Android单点登录,互踢下线代码实现

    Android单点登录,互踢下线代码实现 分享一个在项目中必然会用到的小功能--单点登录,也就是我们常说的互踢下线. 国际惯例,先上效果图 一.先说逻辑,其实挺简单 ​ 首先,对于监听账号是否在其他设 ...

  8. springboot+shiro自定义拦截器互踢问题

    shiro自定义拦截器继承AccessControllerFilter,实现session互踢机制. 应用场景: 我们经常会有用到,当A 用户在北京登录 ,然后A用户在天津再登录 ,要踢出北京登录的状 ...

  9. CAS SSO 单点登录 【完整版】

    什么是单点登录?什么是SSO? SSO就是单点登录!!! SSO即Single Sign On. 可是为什么我们要单点登录呢?为什么不能把所有的系统做成一个war包里呢? 道理很简单啊,如果这个银行这 ...

最新文章

  1. 两条波浪线符号_四年级数学上册第二单元“线的认识”作业单(附带答案)
  2. 使用 Pandas、Jinja 和 WeasyPrint,轻松创建一个 PDF 报表
  3. Matlab篇(三)MATLAB中conj的用法
  4. 企业绩效管理系统之平衡记分卡
  5. java金字塔等边三角形_java99乘法表的小练习 正三角 倒三角 正金字塔 倒金字塔...
  6. 力扣1317.将整数转换为两个无零整数之和
  7. mybatis关联查询之一对多,多对一,以及多对多
  8. cad2020打印样式放在哪个文件夹_打印机故障:打印一直出现乱码,什么原因?...
  9. 运放做跟随器有什么要求
  10. codesys 实现冒泡排序
  11. github访问加速
  12. java——》解析简历
  13. Android Data Binding 初识
  14. html 制作人物模型,玩家制作《辐射4》人物模型图 惊艳无比让人叹服
  15. 让临时停车号码牌会说话--鲁哇客智能挪车号码牌技术升级之路
  16. 【03】Linux笔记
  17. 物联网识别技术期末复习概要
  18. 记账的优缺点分析 聊聊记账这些事
  19. JavaScript中的arguments,callee,caller,call,appy
  20. 开发者举报:“除了每年收我的钱,苹果似乎什么都不想做”

热门文章

  1. 清华大学企业资本运营总裁高级研修班
  2. 用户数据报协议---UDP协议【详解】
  3. 互联网读书-视界互联网+时代的创新与创业
  4. Python 中 selenium 设置参数,不打开可视化页面,后台执行爬虫程序
  5. 按键精灵打怪学习-回城买药加血
  6. 文章阅读总结:OpenAI-Codex
  7. 麒麟os或将取代android,新款操作系统将要诞生!华为研发麒麟OS,网友:取代安卓...
  8. 实木餐桌四大保养方法,90%的人都不知道
  9. fedora如何隐藏顶部状态栏_桌面便签如何始终保持显示,便签如何在桌面显示
  10. 对于Automatic Multi-Sensor Extrinsic Calibration for Mobile Robots的标定方案分析总结