Shiro————会话管理

引言

本篇博客翻译自Shiro 官方网站的 Session Manager 手册。

网页地址:http://shiro.apache.org/session-management.html

Shiro 会话管理支持的特性

  • 基于POJO/J2SE(IoC容器友好的)- Shiro 中的所有东西都是基于接口的,而且是以 POJO作为实现。因此你可以很容易地配置所有兼容 JavaBean 的会话组件,如 JSON,YAML, Spring XML,或者类似的机制。你也可以很容易的扩展Shiro 的组件,或在必要情况下完全自定义 session 管理的功能。
  • 简单的自定义 Session 存储 - 因为 Shiro 的 Session 对象是基于 POJO的,因此 Session 数据可以存储在任意数量的数据源中。因此,你可以自定义你的应用 session 存储的位置,例如,文件系统、内存、分布式的网络缓存、关系型数据库,或者是专有数据存储区。
  • 不依赖容器的集群! - Shiro 的session 可以被任何缓存产品集群管理,如Ehcache + Terracotta, Coherence, GigaSpaces 等等。这意味着你只需要配置一次 Session 集群,不论你的应用会部署到哪种容器,你的 session 都将以同样的方式聚集。不需要针对特定容器的配置。
  • Heterogeneous Client Access - Unlike EJB or Web sessions, Shiro sessions can be ‘shared’ across various client technologies. For example, a desktop application could ‘see’ and ‘share’ the same physical session used by the same user in a web application. We are unaware of any framework other than Shiro that can support this.
  • 事件监听 - 事件监听允许你监听 session 的生命周期。你可以监听它们并对这些事件作出自定义的操作,例如,当某个用户的 session 过期时更新数据库的记录。
  • 主机地址保留 - Shiro Session 会保留发起主机的 IP 地址。因此,你可以据此来确定用户的位置并作出相应的反应(通常在IP 关联关系确定的 内网环境比较有用)
  • 支持用户无操作/过期 - 由于用户无操作而导致 Session 超时是人们期望看到的,但 session 可以通过 touch()方法保持“活跃”。这在富互联网应用环境非常有用,用户可能一直在使用桌面应用,而并没有定期与服务端产生交互,但 server 端的 session 不应该因此而过期。
  • Web 使用透明(无障碍感) - Shiro 对 web 的支持 完全实现了和支持了 Servlet 2.5 对 Session 的规范(HttpSession 接口和与它相关的所有API)。也就是说你可以在已创建的 Web 应用中使用 Shiro 的Session ,而且不需要更改任何代码。
  • 可以使用在 SSO上 - 因为 Shiro 的Session 是基于 POJO 的,它们可以被存储到任意的数据源上,而且,如果需要的话可以在多个应用间进行共享。它还可以提供简单的登录体验,因为共享会话可以保留身份验证状态(单点登录)。

使用 Session

和Shiro 中几乎所有的东西一样,要获得 Session 对象,你需要和当前执行的 用户 产生某种作用。

Subject currentUser = SecurityUtils.getSubject();Session session = currentUser.getSession();
session.setAttribute( "someKey", someValue);

currentUser.getSession() 方法默认调用了 currentUser.getSession(true)。

对于那些熟悉 HttpServletRequest API 的人,Subject.getSession(boolean create) 方法在功能上和HttpServletRequest.getSession(boolean create) 方法完全一致。

  • 如果 Subject 已经有了一个 Session ,布尔类型的参数将被忽略,而直接返回 session 对象。
  • 如果 Subject 还没有一个Session ,且参数为 true,就会创建一个 Session 对象并返回。
  • 如果 Subject 还没有一个 Session ,且参数为 false, 就不会创建 Session ,并且返回 null。

注意:getSession方法的调用在所有应用中都适用,即便不是web 应用。

subject.getSession(false) 在开发框架代码确定不需要创建新的 Session 时,可以获得良好的效果。

一旦你获得了一个 Subject 的 Session ,你可以用它来做许多事情,例如设置和取出属性,设置它的 timeout,等等。参考Session JavaDoc 查看更多信息。

会话管理器

SessionManager,顾名思义,管理应用中所有 subject 的 session  - 创建、删除、无活动过期 等等。和其他 Shiro 中的架构组件一样,SessionManager 对象也是一个被SecurityManager 持有的顶级组件。

默认的 SecurityManager 实现默认使用开箱即用的 DefaultSessionManager。DefaultSessionManager可以提供所有企业级 session 管理特性,如 会话过期、清理等等,且同样适用于所有类型的应用。

Web 应用

Web 应用可以使用不同的 SessionManager实现类。请参考 Web 文档查看 web特定的 Session 管理信息。

和其他被 SecurityManager 管理的组件一样, SessionManager 可以通过JavaBean的形式通过 get、set 方法组装到所有 Shiro 默认的 SecurityManager 实现对象上(getSessionManager()/setSessionManager())。或者例如下面,使用 shiro.ini 配置文件:

[main]
...
sessionManager = com.foo.my.SessionManagerImplementation
securityManager.sessionManager = $sessionManager

但是从头创建一个 SessionManager 是一件非常复杂的任务,大多数人都不愿去做。Shiro的开箱即用的 SessionManager 实现是高度可定制和配置的,同时满足大多数需要。本文档其余部分的大部分假设您将在介绍配置选项时使用Shiro的默认SessionManager实现,但是请注意,实际上您可以创建或插入几乎任何您想要的东西。

Session 超时

默认情况下,SessionManager 的默认会话超时时间是 30分钟。也就是说,如果任何 Session 创建后保持闲置(未使用,即 lastAccessedTime 没有更新)超过 30 分钟或更长,那么 Session 就可能过期,并且不允许再继续使用。

你可以设置默认的 session 超时时间,使用 globalSessionTimeout 属性来为所有的 session 定义默认的超时。例如,如果你希望超时时间是一小时而不是 30分钟:

[main]
...
# 3,600,000 milliseconds = 1 hour
securityManager.sessionManager.globalSessionTimeout = 3600000

单个 session 超时

globalSessionTimeout 限制所有新产生的 session 。你可以为每个 session 设置 timeout 属性。和上面的 globalSessionTimeout一样,这个值也是基于 毫秒的。

Session 监听器

Shiro 支持监听器的概念,允许你在一些非常重要的 session 事件发生时做出动作。你可以实现 SessionListener 接口(或 继承更方便的 SessionListenerAdapter)并且对 Session 操作做出相应的反应。

默认的 SessionManager的sessionListeners 属性 是一个集合,你可以给 SessionManager 配置一个或者多个 监听器实现:

[main]
...
aSessionListener = com.foo.my.SessionListener
anotherSessionListener = com.foo.my.OtherSessionListenersecurityManager.sessionManager.sessionListeners = $aSessionListener, $anotherSessionListener, etc.

所有的 Session 事件

SessionListener 会监听所有的 session 事件,并不是只为了某一个 特定的session 。

Session 存储

不论session 什么时候创建或更新,它的数据都需要持久化到一个存储位置,这样才能让应用程序在接下来的操作中访问到。同样,当一个 Session 失效或者不再使用,也需要从存储空间中删除,以免存储空间耗尽。SessionManager 的实现可以将 session  的 CRUD操作委托给一个系统内部的组件,即 SessionDAO ,它遵从 Data Access Object (DAO)设计模式。

通过实现 SessionDAO 这个接口,你可以和任何你希望的数据存储进行交互。也就是说,你可以把你的 session 数据放到内存、或文件系统、或关系型数据库、或NoSQL 数据库中,或者其他任何地方。你可以完全掌控持久化行为。

你也可以配置任何形式的 SessionDAO 实现装载到默认的SessionManager 实例中,例如,像下面 shiro.ini 这样:

[main]
...
sessionDAO = com.foo.my.SessionDAO
securityManager.sessionManager.sessionDAO = $sessionDAO

当然,人们也期望,Shiro 已经准备了一些优秀的 SessionDAO 的实现,你可以开箱即用,或者继承他们做个性化处理。

Web 应用注意

上面的 securityManager.sessionManager.sessionDAO = $sessionDAO 装载方式只适用于当使用 Shiro 自己的 session 管理器的时候。Web 应用一般情况不使用这种本地session 管理器,而是保留 Servlet 容器的默认 session 管理器,然而这个管理器并不支持 Shiro 的SessionDAO。如果你希望在 Web 应用中使用 Shiro 提供的SessionDAO 接口来定制 session 存储或 session 集群,你必须首先配置一个Shiro 自己的web session 管理器。例如:

[main]
...
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager# Configure a SessionDAO and then set it:
securityManager.sessionManager.sessionDAO = $sessionDAO

(译者注:Shiro native 我翻译成了 Shiro 自己的,者应该是原文所表达的含义,即需要开发者在Web 应用中配置 Shiro 框架为 web应用专门定制的可以支持 SessionDAO 接口的 web session 管理器)

配置 SessionDAO 注意

Shiro 的默认配置 SessionManager 采用 in-memory-only 只读内存方式的Session 存储,这并不适用于大多数生产应用。大多数生产应用会想要配置EHChached 支持并且提供自己的 SessionDAO实现。注意, Web应用使用基于Servlet 容器的SessionManager 作为默认实例因此不用担心这个问题。这个问题只会在使用 Shiro 自己的SessionManager 的时候需要考虑。

EHCache SessionDAO

EHCache 不是默认可用的,但如果你不打算实现自己的 SessionDAO,那就强烈推荐为你的应用添加EHCache 来支持 Shiro 的Session 管理工作。EHCache SessionDAO 会将 session 存储到内存中,并支持当内存逐渐吃紧的情况下溢出到磁盘。这可以非常良好的保证生产应用不会在运行时随机 “丢失” Session。

使用 EHCache 作为你的默认选择

如果你没有自己定制化的 SessionDAO,一定(译者注:这里原文是推荐的口吻)要在你的Shiro 配置中使用EHCache 。EHCache 不仅可以使你的 Session 受益,同样也会对缓存鉴权、授权数据有所帮助。参考Chaching 文档获取更多帮助。

不依赖容器的 Session 集群

如果你迫切需要一个不依赖容器的 session 集群,那EHCache 同样是不错的选择。你可以显式插入一个 TerraCotta 到你的EHCache 中,并拥有一个不依赖容器的集群化的 session 缓存。再也不用担心什么Tomcat、JBoss、Jetty、WebSphere 或者 WebLogic  定制的session 集群了。

为 Session 启用EHCache 非常简单。首先,确保你的项目中已经有了 shiro-ehcache-<version>.jar 文件。

然后,下面的 shiro.ini 示例展示了如何使用 EHCache 支持所有 Shiro 缓存的需要(可不仅仅是 Session 支持哦):

[main]sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
securityManager.sessionManager.sessionDAO = $sessionDAOcacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
securityManager.cacheManager = $cacheManager

最后一行,为所有 Shiro 的需要配置了一个 CacheManager。这个 CacheManager 实例会自动传播到 SessionDAO(默认实现了 CacheManagerWare 接口的 EnterpriseCacheSessionDAO )。

然后,当 SessionManager 要求  EnterpriseCacheSessionDAO  去持久化一个 session 的时候,它会使用一个EHCache 支持的 Cache 实现去存储 session 数据。

web 应用

不要忘记 SessionDAO 是Shiro 框架自己的SessionManager 实现所具备的特性。Web 应用默认使用 基于 Servlet 容器的 SessionManager 是不支持 SessionDAO 的。如果你想在web 应用中使用基于EHCache 的 Session 存储,就需要配置一个Shiro自己的 web SessionManager ,这已经在前面有所说明。

EHCache Session 缓存配置

http://shiro.apache.org/session-management.html#ehcache-session-cache-configuration

未完待续......

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558743.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux进阶之路————磁盘查询

引言 承接《Linux进阶之路————Linux磁盘分区与挂载》&#xff0c;本文介绍实际生产中对于磁盘的监控和查询。 一、查询磁盘整体使用情况 基本语法&#xff1a; df -h 该命令会显示包括我们手动挂载的磁盘&#xff0c;如果使用 umount 卸载磁盘&#xff0c;那么将不会显示…

Linux进阶之路————CentOS网络配置

引言 Linux在装机后&#xff0c;如果没有特殊配置&#xff0c;会使用动态获取 IP 地址的策略。本文描述了&#xff0c;虚拟机使用网络的拓扑图&#xff0c;以及如何通过配置&#xff0c;将 IP 地址固定下来&#xff0c;不会因为重启而失效。同时可以访问外网地址。 一、NAT模…

Linux进阶之路————进程与服务管理

引言 在Linux 中&#xff0c;每个执行的程序&#xff08;代码&#xff09;都成为一个进程&#xff0c;Linux 为每一个进程分配了一个唯一的 id 号 - PID。 每个进程都会对应一个父进程&#xff0c;而这个父进程可以复制多个子进程&#xff0c;例如 www 服务器。 每个进程都可…

Linux进阶之路———— RPM 与 YUM 包管理

引言 rpm 是一种用于互联网下载的打包及安装工具&#xff0c;它包含在某些 Linux 发行版中&#xff0c;生成具有 .rpm 扩展名的文件。rpm 是 redhat package manager&#xff08;RedHat 软件包管理器&#xff09;的缩写&#xff0c;类似 Windows 下的 setup.exe 文件。这一文件…

Linux进阶之路———Shell 编程入门

引言 通过 Shell 编程的学习&#xff0c;铺平架构师道路上的一块大砖。 Shell 在Linux 系统中的定位如下所示&#xff1a; 一、第一个 Shell 脚本 我们通过一个简单的 Shell 脚本来感受一下。 在 Shell 中不需要加 “;” 结尾&#xff0c;通过 vim 可以进行 shell 的编程工…

Linux 实操———CentOS 6 安装配置 Oracle JDK 1.8

引言 本篇博客也属于Linux进阶系列&#xff0c;主要讲解如何在CentOS 6 下安装并配置 JDK 8。由于通过 yum 搜索的结果都是 openjdk&#xff0c;而目前企业中还是以 Oracle jdk 为主&#xff0c;因此&#xff0c;操作步骤这样的。 在Oracle 官网把 jdk 1.8 下载下来&#xff…

Linux 实操———CentOS 6 安装配置 Tomcat

引言 Linux下安装Tomcat。 一、下载、传输与解压 同《Linux 实操———CentOS 6 安装配置 Oracle JDK 1.8》一样&#xff0c;前期都是先在远程机上下载压缩包&#xff0c;然后通过远程终端&#xff0c;将压缩包放在 Linux 的 opt 目录下&#xff0c;然后解压。 下载地址是T…

Spring Boot 实用开发技巧————Eclipse 远程调试

引言 在之前的开发当中&#xff0c;都会进行本地项目启动&#xff0c;然后向本地服务发起请求来进行 Debug 调试代码&#xff0c;这也是开发人员最常见的调试操作。但是当项目逐渐成型&#xff0c;慢慢的将各个模块部署到服务器后&#xff0c;调试的手段可能就仅仅剩下查看执行…

Linux 实操———— Shell 远程执行命令

引言 目前&#xff0c;开发人员的部署方式是&#xff0c;将项目打包(Maven 打包) 然后将 生成的 jar 包等文件&#xff0c;通过Xshell 等终端工具手动传输到远程服务器上&#xff0c;然后再通过在终端执行远程服务器上的 shell 脚本来启动服务。 本篇博客聚焦这样一种解决方案…

Spring Boot 设置 ASCII banner 艺术字

引言 无意中看到Spring boot 项目的 resources 目录下有一个 banner.txt &#xff0c;打开一看&#xff0c;居然是ASCII 字符画。于是兴起&#xff0c;简单研究了一下。 Spring boot 可以加载 resources 目录下的 banner.txt 文件&#xff0c;将字符画在启动之初输出到日志或…

MySQL 基础 ———— 分组查询

引言 承接上一篇《MySQL 基础 ————高频函数总结》&#xff0c;本篇单独针对分组查询进行简单的总结和归纳&#xff0c;并为后续更为复杂的DQL 语句做好铺垫。 查询语句&#xff1a; SELECT AVG(salary) FROM teacher; 实际上是以全表的 salary 字段来求平均值。但是在实…

MySQL 基础 ———— 连接查询

引言 本篇文章承接《数据库与SQL语句》专栏&#xff0c;进入DQL的重要环节&#xff0c;可以说&#xff0c;这一部分的内容应该占据SQL语言的大部分使用场景。 本篇的连接查询知识&#xff0c;和后面的一些重要的查询知识总结&#xff0c;共同构成了在工作中80%的MySQL应用场景…

MySQL 基础 ———— 子查询

引言 承接《MySQL 基础 ———— 连接查询》&#xff0c;本文介绍和展示SQL中子查询的使用。 子查询是出现在其他语句中的select 语句&#xff0c;也称为内查询。外部的查询语句&#xff0c;称为主查询或外查询。 一、子查询的分类和支持的子句 按照子查询出现的位置&#…

MySQL 基础 ———— SQL语句的执行顺序与 LIMIT 子句

引言 到目前为止&#xff0c;已经总结了常见的SQL子句&#xff0c;包括 SELECT 、FROM、JOIN ... ON、WHERE、GROUP BY、HAVING、ORDER BY。 虽然SQL的书写顺序是固定的&#xff0c;但在MySQL引擎中执行的顺序并不完全和书写顺序一致。除了上述这些子句&#xff0c;下面将会介…

MySQL 基础———— UNION 联合查询

引言 联合查询与连接查询不同&#xff0c;通过UNION 关键字&#xff0c;我们可以将多个查询语句一同执行并将结果集展示出来&#xff0c;不涉及到任何关联关系。 UNION 的含义是“联合&#xff0c;并集&#xff0c;结合”&#xff0c;在MySQL中可以将多个查询语句的结果合并成…

MySQL 基础————常用数据类型

引言 从第一次学习mysql开始&#xff0c;不知道为什么MySQL的数据类型始终没有像Java 一样深入脑海&#xff0c;对某些数据类型的定义和用法&#xff0c;也并不清晰&#xff0c;这篇文章&#xff0c;就好好总结一番&#xff0c;将MySQL中几个常用的数据类型归纳一下。 一、类…

MySQL 基础 ———— SAVEPOINT 的应用

引言 savepoint 关键字用于在数据库事务中设置一个存储点&#xff0c;在一个较长的事务中暂存数据&#xff0c;如果在事务末尾执行回滚&#xff0c;可选择性的回滚到 savepoint 设置的暂存点。 本文承接上一篇博客《MySQL 基础 ————事务与隔离级别总结》&#xff0c;进一…

MySQL 基础 ———— 视图的应用与总结

引言 视图是一种虚拟表&#xff0c;和普通表的使用是一样的&#xff0c;视图的一大特点就是“临时性”&#xff0c;是通过表动态生成的数据&#xff0c;只保存SQL逻辑&#xff0c;不保存查询结果。 视图在实际生产中主要有两种应用场景&#xff1a; 1、多个地方用到同样的查…

MySQL 基础 ———— 变量

一、MySQL系统变量 系统变量是由系统提供&#xff0c;属于服务器层面。 系统变量分为&#xff1a;全局变量和会话变量。 全局变量一般要加 GLOBAL 关键字&#xff0c;例如在《MySQL 基础 ————事务与隔离级别总结》中提到的 GLOBAL TRANSACTION&#xff0c;就属于全局变量…

MySQL 基础 ———— 存储过程与函数

一、存储过程介绍 存储过程是一组预先编译好的SQL语句的集合&#xff0c;可理解成批处理语句。它的优点主要有以下几点&#xff1a; 1、提高代码的重用性&#xff1b; 2、简化操作&#xff1b; 3、减少了编译次数并且减少了和数据库服务器的连接次数&#xff0c;提高了效率…