第七章:Shiro的Session管理——深入浅出学Shiro细粒度权限开发框架
概述和配置使用
n概述
Shiro提供安全框架界独一无二的东西:一个完整的企业级Session 解决方案,可以为任意的应用提供session支持,包括web和非web应用,并且无需部署你的应用程序到Web 容器或使用EJB容器。
n基本使用
可以通过与当前执行的Subject 交互来获取Session:
Subject currentUser = SecurityUtils.getSubject();
Session session = currentUser.getSession();
session.setAttribute("someKey", someValue);
n关于SessionManager
SessionManager是用来管理Session的组件,包括:创建,删除,inactivity(失效)及验证,等等。SessionManager 也是一个由SecurityManager 维护的顶级组件。
shiro提供了默认的SessionManager实现,一般没有必要自定义这个。
n设置Sessioin的过期时间
Shiro 的SessionManager 实现默认是30 分钟会话超时。
你可以设置SessionManager 默认实现的globalSessionTimeout 属性来为所有的会话定义默认的超时时间。例如,
[main]
# 3,600,000 milliseconds = 1 hour
securityManager.sessionManager.globalSessionTimeout = 3600000
nSessioin的事件监听
你可以实现SessionListener 接口(或扩展易用的SessionListenerAdapter)并与相应的会话操作作出反应。 配置示例:
[main]
aSessionListener = com.foo.my.SessionListener
anotherSessionListener = com.foo.my.OtherSessionListener
securityManager.sessionManager.sessionListeners = $aSessionListener, $anotherSessionListener
SessionDAO
n概述
每当一个会话被创建或更新时,它的数据需要持久化到一个存储位置以便它能够被稍后的应用程序访问,实现这个功能的组件就是SessionDAO。
你能够实现该接口来与你想要的任何数据存储进行通信。这意味着你的会话数据可以驻留在内存中,文件系统,关系数据库或NoSQL 的数据存储,或其他任何你需要的位置。
n基本配置 SessionDAO是作为一个属性配置在默认的SessionManager 实例上
[main]
sessionDAO = com.foo.my.SessionDAO
securityManager.sessionManager.sessionDAO = $sessionDAO
这种SessionDAO主要在本地应用中起作用。
n基于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
nShiro提供了默认的EHCache的配置xml,如果你要配置自己的EHCache.xml,需要注意以下几点:
1:overflowToDisk=“true” - 这确保当你溢出进程内存时,会话不丢失且能够被序列化到磁盘上。
2: eternal=“true” - 确保缓存项(Session 实例)永不过期或被缓存自动清除。这是很有必要的,因为Shiro 基于计划过程完成自己的验证。如果我们关掉这项,缓存将会在Shiro 不知道的情况下清扫这些Sessions,这可能引起麻烦。
3:如果你想使用一个不同的名字而不是默认的,你可以在EnterpriseCacheSessionDAO 上配置名字,例如:sessionDAO.activeSessionsCacheName = myname
只要确保在ehcahe.xml 中有一项与这个名字匹配
Web应用中的Session
n在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
n在web应用上,如果想要在每一个请求的基础上启用或禁用会话的创建,可以在配置中的[urls] 里面,为相应的url设置一个noSessionCreation过滤器,如下:
[urls]
/rest/** = noSessionCreation, authcBasic
自定义SessionDAO
n在某些场景中,我们需要管理用户的Session信息,比如把Session信息放到数据库中,这样就可以记录一个操作日志,或是统计在线人员等等。
n自定义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);
}
}
n基本的配置示例:
sessionDAO = cn.javass.hello.MySessionDAO
securityManager.sessionManager.sessionDAO = $sessionDAO
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- C++基础 多线程笔记(一)
- C++基础 数据类型占字节大小分析
- socket方式传输文件
- 《重构-代码整洁之道TypeScript版》第2天
- 堆积柱形图(stacked barplot)展示密码子偏向性的RSCU值
- 《重构-代码整洁之道TypeScript版》第一天
- Hive小知识之分桶抽样
- CountDownLatch类在性能测试中应用
- 算法集锦(20) | 自动驾驶 | 交通标志识别算法
- 敏捷回归测试
- 算法集锦(21) | 自动驾驶 |汽车转向角控制算法
- Java压缩/解压缩字符串
- 凉经算法题反思 | 单调栈与DP二分法
- 终于有人把Docker讲清楚了!
- 飞天茅台超卖事故:Redis分布式锁请慎用!