Shiro提供的功能结构图:

Shiro详细的架构:

Shiro中的各类过滤器

Filter Name Class
anon org.apache.shiro.web.filter.authc.AnonymousFilter
authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
logout org.apache.shiro.web.filter.authc.LogoutFilter
noSessionCreation org.apache.shiro.web.filter.session.NoSessionCreationFilter
perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port org.apache.shiro.web.filter.authz.PortFilter
rest org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
roles org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl org.apache.shiro.web.filter.authz.SslFilter
user org.apache.shiro.web.filter.authc.UserFilter

单一登录:同一个账户同一时间只能在一个地方登录。
项目Spring+SpringMVC+Mybatis,引入了Shiro作认证授权。公司要求实现一个单一登录功能,大部分人做法都是在自定义实现Realm的doGetAuthenticationInfo里面做session过滤和删除,这在没有启用Shiro的rememberMe功能是可以生效的,但是启用了rememberMe功能后,会发现session移除无效,用户仍然可以登录。

Realm中doGetAuthenticationInfo实现

 @Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String userName = (String) token.getPrincipal();UserEntity user = userService.queryByLoginName(userName);if (user == null) {throw new AuthenticationException("帐号密码错误");}//错误次数控制checkLoginErrorTimes(userName);//单一登录控制checkSingleSingOn(user);SimpleAuthenticationInfo sainfo = new SimpleAuthenticationInfo(user, user.getPassWord(), ByteSource.Util.bytes(user.getSalt()), getName());return sainfo;}

单一登录控制:

    /*** 用户单一登录* @param user 用户实体*/private void checkSingleSingOn(UserEntity user) {DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();DefaultWebSessionManager sessionManager = (DefaultWebSessionManager) securityManager.getSessionManager();//获取当前已登录的用户session列表SessionDAO sessionDAO = sessionManager.getSessionDAO();Collection<Session> sessions = sessionDAO.getActiveSessions();for (Session session : sessions) {//清除该用户以前登录时保存的sessionif (user.getId().equals(String.valueOf(session.getAttribute("userId")))) {// 清除认证缓存sessionDAO.delete(session);}}}

RememberAuthenticationFilter实现

public class RememberAuthenticationFilter extends FormAuthenticationFilter{@Overrideprotected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {Subject subject = getSubject(request, response);//如果 isAuthenticated 为 false 证明不是登录过的,同时 isRememberd 为true 证明是没登陆直接通过记住我功能进来的if(!subject.isAuthenticated() && subject.isRemembered()){//获取session看看是不是空的Session session = subject.getSession();// 用于处理单一登录问题,由于使用了rememberMe功能,所以导致移除session用户身份仍然短期有效,这边做登出处理if(session.getAttribute("userId") == null){subject.logout();}}//这个方法本来只返回 subject.isAuthenticated() 现在我们加上 subject.isRemembered() 让它同时也兼容remember这种情况return subject.isAuthenticated() || subject.isRemembered();}}

1、没有在RememberMe中做过滤的场景

初始化时,Redis中没有任何数据。

第一次登录,创建了一个用户的Session(Chrome)

第二次登录清除了第一次登录的session,但是同时又创建了新的session(Firefox)


刷新第一次登录的页面,会发现多了两个session-id,并且页面用户凭证仍然有效,session被重建了···(这里是由于RememberMe的机制干扰,导致了单一 登录的功能无法正常控制)

2、在RememberMe加入过滤后以同样的方式进行

第一次登录,创建了一个用户的Session(Chrome)

第二次登录清除了第一次登录的session,但是同时又创建了新的session(Firefox)


刷新第一次登录的页面,redis里面的session没有新增,session没有重建,而是跳转到登录页面,成功。

Shiro实现单一登录,并保留使用RememberMe功能。相关推荐

  1. [shiro] - 加入rememberMe功能

    shiro不加入rememberMe没事,一加入就出错. RememberMeAuthenticationToken : public interface RememberMeAuthenticati ...

  2. openid saml2_单一登录云:SAML和OpenId

    openid saml2 当访问不同组织拥有的不同应用程序时,每次从一个应用程序转到另一个应用程序时都必须进行身份验证. 这不仅耗时,而且您还必须记住多个经常丢失的密码. 单一登录是一次认证的能力,并 ...

  3. 单一登录云:SAML和OpenId

    当访问不同组织拥有的不同应用程序时,每次从一个应用程序转到另一个应用程序时都必须进行身份验证. 不仅浪费时间,而且您还必须记住多个经常丢失的密码. 单一登录是一次认证的能力,并且能够使用已认证的身份在 ...

  4. Shiro实现rememberMe功能

    一.介绍 Shiro提供了记住我(RememberMe) 的功能,比如访问一些网站时,关闭了浏览器,下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问. 基本流程 首先在登录页面选中Remem ...

  5. Shiro的 rememberMe 功能使用指导(为什么rememberMe设置了没作用?)

    问题 shiro中提供了rememberMe功能,它用起来是这样的 UsernamePasswordToken token = new UsernamePasswordToken(loginForm. ...

  6. Shiro学习之RememberMe功能实现

    目录 前言 更换MySQL数据库 一.更换依赖 二.更改配置 三.改换建表语句 Shiro的配置 控制层的改进 实际展示 咨询请找 前言 在网上看了一个开源的springboot项目,上面有非常全的s ...

  7. Shiro 实现 RememberMe 功能

    本文内容:Shiro 中RememberMe 功能的介绍以及实现. 1 介绍 Shiron 提供了记住我(RememberMe)的功能,比如访问如淘宝等一些网站时,关闭了浏览器下次再打开时还是能记住你 ...

  8. Apache Shiro(七)——Shiro的RememberMe功能

    一.概述 Shiro 提供了记住我(RememberMe)的功能,比如访问如淘宝等一些网站时,关闭了浏览器,下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问,基本流程如下: 1.首先在登录页 ...

  9. Apache Shiro实现用户登录功能

    apache shiro实现用户登录功能 配置shiro的Filter实现URL级别权限控制 配置web.xml <!-- shiro的过滤器 --> <filter>< ...

最新文章

  1. 三次握手、四次挥手理解
  2. LSTM预测MNIST手写数字张量流图分析
  3. 搭建Ubuntu18.04+Anaconda3.x+Pycharm+SimpleITK(三)
  4. python为什么这么火 知乎-没想到 Google 排名第一的编程语言,为什么会这么火?...
  5. single-number-ii
  6. cout的输出格式初探2
  7. C# TTS-文本转语音
  8. redis设置键的生存时间或过期时间
  9. sturct stat 结构体中 st_mode 的含义
  10. python自动化办公真的好用吗-python如何实现自动化办公?
  11. 【转】设计模式六大原则(1):单一职责原则
  12. Xamarin自学教程(Android)之一
  13. 如何更新一台计算机的驱动程序,怎样更新电脑最新驱动程序? -电脑资料
  14. 京东上位2018年财富中国500强民企第一席 首次实现全年盈利
  15. 设计模式(博客园精化集)〈转〉
  16. android -- 蓝牙 bluetooth解读
  17. 数据可视化——坐标轴的定制
  18. 安全知识云服务器ip端口网络 socket 编程 端口 大全
  19. Tailwind教程1 - 开始使用
  20. 学计算机买笔记本是i5 i7,i7一定比i5强?买电脑陷阱你一定要注意了

热门文章

  1. 逆变器质量堪忧 影响光伏电站运行
  2. 斯蒂夫乔布斯传札记:第二波
  3. 分类问题中的评价指标(F1-Score、Micro-F1、Macro-F1)
  4. Golang二进制反汇编
  5. 揭秘,嵌入式OTA技术,到底有多复杂?
  6. 6.27王者荣耀说服务器在维护,2019.6.27 王者荣耀更新内容 6月27日王者荣耀更新内容...
  7. quartz怎么玩?(基本使用和入门)
  8. 改进后的第二版Retropie树莓派掌机(三)
  9. 第十五届深圳文博会精彩闭幕:非遗生活挥师汉文化产业、引擎汉文化产业繁荣发展...
  10. 为什么我们要学普通话?方言衰落的原因是什么?