前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Shiro会话管理/前后分离身份鉴别原理

Shiro会话管理/前后分离身份鉴别原理

作者头像
devi
发布于 2021-08-19 07:02:38
发布于 2021-08-19 07:02:38
1.6K00
代码可运行
举报
文章被收录于专栏:搬砖记录搬砖记录
运行总次数:0
代码可运行

目录


我们常用 SecurityUtils.getSubject().getPrincipal();获取当前登录用户信息,但是这个方法是如何获得用户信息的?Shiro又是如何区分不同用户的身份的?

问题1. SecurityUtils.getSubject().getPrincipal()返回类型;

查看源码得知它是Object,但是实际上,他的返回类型由我们控制。

在Realm类中有个doGetAuthenticationInfo方法,我们常在这里进行登录逻辑处理,其返回类型是AuthenticationInfo,我们通常使用SimpleAuthenticationInfo,追进去可以看到其第一个参数就是principal,即我们的用户类型:

因此,如果我们最终

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
User user = new User();
user.setPassword("111");
user.setName("sxuer");
return new SimpleAuthenticationInfo(user, user.getPassword(), getName());

则SecurityUtils.getSubject().getPrincipal()将得到User类。 若

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String user = "sxuer";
return new SimpleAuthenticationInfo(user, "123", user);

则SecurityUtils.getSubject().getPrincipal()将得到字符串。

问题2. Shiro如何利用session保持会话

先说结果:

  • 若使用Shiro默认的session会话管理:用户登录–>创建session–>创建cookie–>用户二次访问–>从cookie中读取sessionId–>根据sessionId取得用户身份
  • 若使用自定义的session会话管理,适用于前后分离(但需要解决跨域cookie禁止问题):用户登录,同时携带sId–>检查到sId参数,使用自定义getsessionId方法–>保存sessionId到cookie中–>用户二次访问,携带sessionId–>根据sessionId取得用户身份

上述两者的主要区别在于,第二种用户登录时,需要携带一个额外的参数,用于创建后续访问的sessionId。

原理

很容易得知,Shiro中有个会话管理器DefaultWebSessionManager,既然Shiro使用session保持会话,那么核心就在于session的创建以及获取(校验)。

DefaultWebSessionManager中有个getSessionId方法,向上追溯,可以发现Shiro会从request中查询cookie,如果找到了,那就作为sessionId保存–>可以得出,sessionId其实是由客户端控制的。如果从cookie中没找到,就从uri中读取JSESSIONID参数,如果依旧没有,就会抛出找不到的异常。

我们可以重写getSessionId方法,从而实现session的定制(若将cache换成redis,就跟传统上使用redis保存token的原理基本一致)。

假设重写的getSessionId如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
        // 如果参数中包含“__sid”参数,则使用此sid会话。 例如:http://localhost/project?__sid=xxx&__cookie=true
        String sid = request.getParameter("__sid");
        if (StringUtils.isNotBlank(sid)) {
            // 是否将sid保存到cookie,浏览器模式下使用此参数。
            if (WebUtils.isTrue(request, "__cookie")) {
                HttpServletRequest rq = (HttpServletRequest) request;
                HttpServletResponse rs = (HttpServletResponse) response;
                Cookie template = getSessionIdCookie();
                Cookie cookie = new SimpleCookie(template);
                cookie.setValue(sid);
                cookie.saveTo(rq, rs);
            }
            // 设置当前session状态
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
                    ShiroHttpServletRequest.URL_SESSION_ID_SOURCE); // session来源与url
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sid);
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
            return sid;
        } else {
            return super.getSessionId(request, response);
        }
    }

当用户登录时,携带了参数__sid=1,那么Shiro会利用该参数创建session,但是并非该值就是session。

Shiro中有个类叫做SessionDao,显然是用于创建Session的,我们进入查看,会发现有个doCreate,阅读之后可以发现,他会利用sessionIdGenerator生成sessionId,然后使用assignSessionId(session, sessionId)将sessionId设置到session对象中。然后在Cache类中(如CachingSessionDao)以sessionId:session作为键值对保存。

获取sessionId: 从cookie中获取session 若为空,则创建session,保存到cookie中,保存到本地Cache中

相关方法: getSessionId(ServletRequest request, ServletResponse response) getSessionIdCookieValue(request, response) readValue(HttpServletRequest request, HttpServletResponse ignored) getCookie(request, name) cookie.getValue(); request.setAttribute

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/11/19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
SaaS-HRM中的认证授权
实现基于Shiro的SaaS平台的统一权限管理。我们的SaaS-HRM系统是基于微服务构建,所以在使用Shiro鉴权的时候,就需要将认证信息保存到统一的redis服务器中完成。这样,每个微服务都可以通过指定cookie中的sessionid获取公共的认证信息。
cwl_java
2020/01/02
7740
快速学习Shiro-Shiro中的会话管理
在shiro里所有的用户的会话信息都会由Shiro来进行控制,shiro提供的会话可以用于JavaSE/JavaEE环境,不依赖于任何底层容器,可以独立使用,是完整的会话模块。通过Shiro的会话管理器(SessionManager)进行统一的会话管理
cwl_java
2020/01/02
1K0
SpringBoot邂逅Shiro-前后端分离时的配置
本篇仅是记录集成的基础过程,至于shiro框架的基础概念和使用细节,可以自行查阅相关资料,本文不做讨论。
WindCoder
2018/09/19
6.4K0
Springboot + Vue + shiro 实现前后端分离、权限控制
前端从后端剥离,形成一个前端工程,前端只利用Json来和后端进行交互,后端不返回页面,只返回Json数据。前后端之间完全通过public API约定。
Java团长
2019/05/21
3.5K0
Shiro实战(五) - 会话管理
Shiro提供了完整的企业级会话管理功能,不依赖于底层容器(如web容器Tomcat),不管JavaSE还是JavaEE环境都可以使用,提供了会话管理、会话事件监听、会话存储/持久化、容器无关的集群、失效/过期支持、对Web的透明支持、SSO单点登录的支持等特性 即直接使用Shiro的会话管理可以直接替换Web容器的会话管理
JavaEdge
2018/11/29
2.5K0
Shiro实战(五) - 会话管理
Springboot+Vue+shiro实现前后端分离、权限控制
本文总结自实习中对项目对重构。原先项目采用Springboot+freemarker模版,开发过程中觉得前端逻辑写的实在恶心,后端Controller层还必须返回Freemarker模版的ModelAndView,逐渐有了前后端分离的想法,由于之前比没有接触过,主要参考的还是网上的一些博客教程等,初步完成了前后端分离,在此记录必备查阅。
用户4283147
2022/10/27
4620
SpringBoot 整合 Shiro 实现动态权限加载更新+ Session 共享 + 单点登录
来源:Sans_ juejin.im/post/5d087d605188256de9779e64
芋道源码
2019/12/24
9390
SpringBoot 整合 Shiro 实现动态权限加载更新+ Session 共享 + 单点登录
Shiro登录校验
shiro是一种权限认证框架,实现一个简单的登录鉴权: 1、控制器层: @Controller @RequestMapping("/blogger") public class BloggerCont
用户1141560
2017/12/26
1.6K0
Java sessionID 一直变化的解决方案「建议收藏」
最近在开发一个项目,测试的人员给我说IOS的登录不上去,由于我和他不是一起的,不能面对面的调试,我就自己找问题喽。
全栈程序员站长
2022/09/13
2.5K0
SpringBoot2.0 整合 Shiro 框架,实现用户权限管理
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。作为一款安全框架Shiro的设计相当巧妙。Shiro的应用不依赖任何容器,它不仅可以在JavaEE下使用,还可以应用在JavaSE环境中。
知了一笑
2019/07/19
9490
Springboot集成Shiro(前后端分离)
shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证、用户授权。
Ant丶
2022/03/01
3.4K0
Springboot集成Shiro(前后端分离)
Shiro 集成 Spring 之会话管理
Shiro 提供了完整的会话管理功能,可以在不依赖底层容器,不仅可以在 WEB 环境下使用 Session,还可以在 JavaSE 环境下使用,且提供了会话管理,会话事件监听,会话持久化,过期支持。
一份执着✘
2018/10/08
8930
Shiro
文章目录 1. 项目搭建 2. Realm 2.1. 子类 2.2. 自定义Realm 2.3. 认证信息的缓存 2.4. 密码加密认证 3. 缓存管理器(CacheManager) 3.1. 清除缓存 3.2. 实现原理 4. 会话管理器(SessionManager) 4.1. 自定义SessionMananger 4.2. 自定义SessionDao 4.3. 自定义SessionId生成策略 4.4. 自定义Session监听器 4.5. 完成上述配置 4.6. 优化 4.7. 会话验证 4.7
爱撒谎的男孩
2019/12/31
1.6K0
补习系列- springboot 整合 shiro一指禅
Apache Shiro 是一个强大且易用的Java安全框架,用于实现身份认证、鉴权、会话管理及加密功能。 框架提供了非常简单且易于上手的API,可以支持快速为web应用程序实现安全控制能力。
美码师
2018/08/27
9310
补习系列- springboot 整合 shiro一指禅
shiro、jwt、redis整合
HTTP协议(1.1)是无状态的,所以服务器在需要识别用户访问的时候,就要做相应的记录用于跟踪用户操作,这个实现机制就是Session。当一个用户第一次访问服务器的时候,服务器就会为用户创建一个Session,每个Session都有一个唯一的SessionId(应用级别)用于标识用户。
全栈程序员站长
2022/07/09
5750
安全之剑:深度解析 Apache Shiro 框架原理与使用指南
在现代软件开发中,安全性一直是至关重要的一个方面。随着网络攻击和数据泄露的不断增加,我们迫切需要一种强大而灵活的安全框架来保护我们的应用。Shiro框架就是这样一把利剑,它能够轻松地集成到你的项目中,为你的应用提供可靠的安全性保护。
繁依Fanyi
2024/01/27
1.6K0
基于权限安全框架Shiro的登录验证功能实现
目前在企业级项目里做权限安全方面喜欢使用Apache开源的Shiro框架或者Spring框架的子框架Spring Security。
SmileNicky
2019/01/17
8400
认识Shiro框架
Subject:Subject一般来说代表当前登录的用户,我们可以在自己的代码中很容易的获取到Subject对象
全栈程序员站长
2022/10/04
5240
Spring集成shiro做登陆认证
  其实很早的时候,就在项目中有使用到shiro做登陆认证,直到今天才又想起来这茬,自己抽空搭了一个spring+springmvc+mybatis和shiro进行集成的种子项目,当然里面还有很简单的测试。本文将讲述在maven下如何进行集成,希望对你有所帮助,喜欢请推荐。至于shiro相关的,最近也会写几篇介绍的,希望能够有一个主观的了解。
阿豪聊干货
2018/08/09
4530
springboot整合shiro实现权限控制
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。上个月写了一个在线教育的项目用到了shiro权限控制,这几天又复盘了一下,对其进行了深入探究,来总结一下。
jiankang666
2022/05/12
4450
springboot整合shiro实现权限控制
相关推荐
SaaS-HRM中的认证授权
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验