第七章:Shiro的Session管理——深入浅出学Shiro细粒度权限开发框架

概述和配置使用

概述

  Shiro提供安全框架界独一无二的东西:一个完整的企业级Session 解决方案,可以为任意的应用提供session支持,包括web和非web应用,并且无需部署你的应用程序到Web 容器或使用EJB容器。

基本使用

  可以通过与当前执行的Subject 交互来获取Session:

  Subject currentUser = SecurityUtils.getSubject();

  Session session = currentUser.getSession();

  session.setAttribute("someKey", someValue);

关于SessionManager

  SessionManager是用来管理Session的组件,包括:创建,删除,inactivity(失效)及验证,等等。SessionManager 也是一个由SecurityManager 维护的顶级组件。

  shiro提供了默认的SessionManager实现,一般没有必要自定义这个。

设置Sessioin的过期时间

  Shiro 的SessionManager 实现默认是30 分钟会话超时。

  你可以设置SessionManager 默认实现的globalSessionTimeout 属性来为所有的会话定义默认的超时时间。例如,

[main]

# 3,600,000 milliseconds = 1 hour

securityManager.sessionManager.globalSessionTimeout = 3600000

Sessioin的事件监听

  你可以实现SessionListener 接口(或扩展易用的SessionListenerAdapter)并与相应的会话操作作出反应。 配置示例:

[main]

aSessionListener = com.foo.my.SessionListener

anotherSessionListener = com.foo.my.OtherSessionListener

securityManager.sessionManager.sessionListeners = $aSessionListener, $anotherSessionListener

SessionDAO

概述

  每当一个会话被创建或更新时,它的数据需要持久化到一个存储位置以便它能够被稍后的应用程序访问,实现这个功能的组件就是SessionDAO。

  你能够实现该接口来与你想要的任何数据存储进行通信。这意味着你的会话数据可以驻留在内存中,文件系统,关系数据库或NoSQL 的数据存储,或其他任何你需要的位置。

基本配置    SessionDAO是作为一个属性配置在默认的SessionManager 实例上

[main]

sessionDAO = com.foo.my.SessionDAO

securityManager.sessionManager.sessionDAO = $sessionDAO

这种SessionDAO主要在本地应用中起作用。

基于EHCache的SessionDAO,基本配置如下:

[main]

sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO

securityManager.sessionManager.sessionDAO = $sessionDAO

cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager

securityManager.cacheManager = $cacheManager

Shiro提供了默认的EHCache的配置xml,如果你要配置自己的EHCache.xml,需要注意以下几点:

1:overflowToDisk=“true” - 这确保当你溢出进程内存时,会话不丢失且能够被序列化到磁盘上。

2: eternal=“true” - 确保缓存项(Session 实例)永不过期或被缓存自动清除。这是很有必要的,因为Shiro 基于计划过程完成自己的验证。如果我们关掉这项,缓存将会在Shiro 不知道的情况下清扫这些Sessions,这可能引起麻烦。

3:如果你想使用一个不同的名字而不是默认的,你可以在EnterpriseCacheSessionDAO 上配置名字,例如:sessionDAO.activeSessionsCacheName = myname

  只要确保在ehcahe.xml 中有一项与这个名字匹配

Web应用中的Session

在web应用上,默认使用的是容器的会话,如果你想基于Web 应用程序启用SessionDAO 来自定义会话存储或会话群集,你将不得不首先配置一个本地的Web 会话管理器。例如:

[main]

sessionManager=org.apache.shiro.web.session.mgt.DefaultWebSessionManager

securityManager.sessionManager = $sessionManager

# Configure a SessionDAO and then set it:

securityManager.sessionManager.sessionDAO = $sessionDAO

在web应用上,如果想要在每一个请求的基础上启用或禁用会话的创建,可以在配置中的[urls] 里面,为相应的url设置一个noSessionCreation过滤器,如下:

[urls]

/rest/** = noSessionCreation, authcBasic

自定义SessionDAO

在某些场景中,我们需要管理用户的Session信息,比如把Session信息放到数据库中,这样就可以记录一个操作日志,或是统计在线人员等等。

自定义SessionDAO也非常简单,通常是继承AbstractSessionDAO,实现对Session数据的CRUD即可,简单示例如下:

public class MySessionDAO extends AbstractSessionDAO{

private Map<Serializable,Session> map = new HashMap<Serializable,Session>();

  public void update(Session session) throws UnknownSessionException {

  System.out.println("now update session");

  map.put(session.getId(),session);

  }

  public void delete(Session session) {

  System.out.println("now delete session"); 

  map.remove(session.getId());

  }

  public Collection<Session> getActiveSessions() {

  System.out.println("now getActiveSessions session");

  return map.values();

  }

  protected Serializable doCreate(Session session) {

  System.out.println("now doCreate session");

  Serializable sessionId = generateSessionId(session);

      assignSessionId(session, sessionId);

      map.put(sessionId, session);

     return sessionId;

  }

  protected Session doReadSession(Serializable sessionId) {

  System.out.println("now doReadSession session");

  return map.get(sessionId);

  }

}

基本的配置示例:

sessionDAO = cn.javass.hello.MySessionDAO

securityManager.sessionManager.sessionDAO = $sessionDAO

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏开发技术

spring集成mybatis实现mysql读写分离

       在网站的用户达到一定规模后,数据库因为负载压力过高而成为网站的瓶颈。幸运的是目前大部分的主流数据库都提供主从热备功能,通过配置两台数据库主从关系,...

18710
来自专栏惨绿少年

磁盘管理 之 parted命令添加swap,文件系统

第1章 磁盘管理 1.1 必须要了解的。 1.1.1 ps aux 命令中 RSS 与VSZ的含义 rss 进程占用的物理内存的大小 单位:kb ;   ...

28700
来自专栏魏琼东

分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载

     在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于...

13200
来自专栏JavaEdge

Shiro 实战(四) - 过滤器机制1 简介2 过滤器链

NameableFilter给Filter起个名字,如果没有设置默认就是FilterName 当我们组装拦截器链时会根据这个名字找到相应的拦截器实例

29410
来自专栏简单聊聊Spark

Spark内核分析之Shuffle操作流程(非常重要)

        如题,我们来分析一下spark的shuffle操作原理;为什么说其非常重要,是因为shuffle操作是我们在Spark调优中非常重要的一环,对s...

14030
来自专栏一个爱瞎折腾的程序猿

asp.net core使用Swashbuckle.AspNetCore(swagger)生成接口文档

开局一张图,然后开始编,一些基本的asp.net core东西就不再赘述,本文只对Swashbuckle.AspNetCore的几个使用要点进行描述。

19710
来自专栏iOS技术杂谈

iOS多线程——你要知道的GCD都在这里你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里

你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里 转载请注明出处 https://cloud.tencent.co...

525100
来自专栏海天一树

Python Selenium爬取百度百科旅游景点的基本信息

在与python文件同级的目录下创建scenic_spots_5A_namelist.txt,内容为

12920
来自专栏Java帮帮-微信公众号-技术文章全总结

JavaWeb11-jsp.cookie.session(1)

? Jsp&cookie & session 一.jsp 1. jsp的介绍 JSP全名为Java Server Pages,中文名叫java服务器页面,本质...

30750
来自专栏kl的专栏

spring boot集成WebSocket实时输出日志到web页面

前言碎语 今天来做个有趣的东西,就是实时将系统日志输出的前端web页面,因为是实时输出,所有第一时间就想到了使用webSocket,而且在spring boot...

1.2K100

扫码关注云+社区

领取腾讯云代金券