Apache Shiro SessionManager配置详解.

SessionManager是在应用程序中为全部Subject提供Session的管理,包括建立,删除,失效及验证等。同其的核心组件同样,SessionManager 也是一个由SecurityManager 维护的顶级组件。 在Shiro中默认提供了一个SessionManager的实现DefaultSessionManager。DefaultSessionManager 提供一个应用程序所需的全部企业级会话管理。能够在任何应用程序中使用。 若是想自定义一个SessionManager,可在Shiro.ini中配置。例如: [main] … sessionManager = com.foo.my.SessionManagerImplementation securityManager.sessionManager = $sessionManager 在系统中SessionManager 能够经过JavaBean 风格的getter/setter 方法获取或设置(getSessionManager()/setSessionManager())。 下面介绍默认的SessionManager包含的一些额配置项: Session Timeout 默认是30 分钟。也就是说,若是任何Session 建立后闲置(未被使用,未被更新)的时间超过了30 分钟,那么该Session 就被认为是过时的,且不容许再被使用。 你能够经过globalSessionTimeout 属性来为全部的会话定义默认的超时时间。例如,若是你想超时时间是一个小时而不是30 分钟: [main] … # 3,600,000 milliseconds = 1 hour securityManager.sessionManager.globalSessionTimeout = 3600000 Per-Session Timeout 上面的globalSessionTimeout 值默认是为全部新建的Session 使用的。你能够在每个会话的基础上控制超时时间经过设置单独的会话超时时间值。与上面的globalSessionTimeout 同样,该值以毫秒(不是秒)为时间单位。 Session Listeners Shiro 支持SessionListener 概念来容许你对发生的重要会话做出反应。你能够实现SessionListener 接口(或扩展易用的SessionListenerAdapter)来与相应的会话操做做出反应。 因为默认的SessionManager sessionListeners 属性是一个集合,你能够对SessionManager 配置一个或多个listener 实现,就像其余在shiro.ini 中的集合同样: [main] … aSessionListener = com.foo.my.SessionListener anotherSessionListener = com.foo.my.OtherSessionListener securityManager.sessionManager.sessionListeners = $aSessionListener, $anotherSessionListener, etc. 当任何会话事件发生时,SessionListeners 都会被通知——不只仅是对一个特定的会话。 Session Storage 每当一个会话被建立或更新时,它的数据须要持久化到一个存储位置以便它可以被稍后的应用程序访问。一样地,当一个会话失效且再也不被使用时,它须要从存储中删除以便会话数据存储空间不会被耗尽。SessionManager 实现了这些Create/Read/Update/Delete(CRUD)操做作为内部组件,同时,经过SessionDAO反映了数据访问对象(DAO)设计模式。 SessionDAO 的做用是你可以经过该接口来与你想要的任何数据存储进行通讯。这意味着你的会话数据能够驻留在内存中,文件系统,关系数据库或NoSQL 的数据存储,或其余任何你须要的位置。 你能够将任何SessionDAO 实现做为一个属性配置在默认的SessionManager 实例上。例如,在shiro.ini 中: [main] … sessionDAO = com.foo.my.SessionDAO securityManager.sessionManager.sessionDAO = $sessionDAO Shiro 已经有一些很好的SessionDAO 实现,你能够当即使用或实现你须要的子类。 EHCache SessionDAO EHCache 默认是没有启用的,但若是你不打算实现你本身的SessionDAO,那么强烈地建议你为Shiro 的SessionManagerment 启用EHCache 支持。EHCache SessionDAO 将会在内存中保存会话,并支持若内存不足时可溢出到磁盘。这对确保你在运行时不会随机地“丢失”会话是很是好的。 为全部Shiro 的缓存须要使用EHCache: [main] sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO securityManager.sessionManager.sessionDAO = $sessionDAO cacheManager = org.apache.shiro.cache.ehcache.EhcacheManager securityManager.cacheManager = $cacheManager 最后一行,securityManager.cacheManager = $cacheManager,为全部Shiro 的须要配置了一个CacheManager。该CacheManager 实例会自动地直接传送到SessionDAO(经过EnterpriseCacheSessionDAO 实现CacheManagerAware 接口的性质)。 而后,当SessionManager 要求EnterpriseCacheSessionDAO 去持久化一个Session 时,它使用一个EHCache 支持的Cache实现去存储Session 数据。 Custom Session IDs Shiro 的SessionDAO 在建立一个新的会话时使用一个内置的SessionIdGenerator 组件来产生一个新的Session ID。该ID 生成后,被指派给新近建立的Session 实例,而后该Session 经过SessionDAO 被保存下来。 默认的SessionIdGenerator 是一个JavaUuidSessionIdGenerator,它能产生基于Java UUIDs 的String IDs。该实现可以支持全部的生产环境。 若是它不符合你的须要,你能够实现SessionIdGenerator 接口并在Shiro 的SessionDAO 实例上配置该实现。例如,在shiro.ini 中: [main] ... sessionIdGenerator = com.my.session.SessionIdGenerator securityManager.sessionManager.sessionDAO.sessionIdGenerator = $sessionIdGenerator Session Validation & Scheduling Sessions 必须被验证,这样任何无效(过时或中止)的会话可以从会话数据存储中删除。这保证了数据存储不会因为不能再次使用的会话而致使写入超时。 因为性能上的缘由,仅仅在Sessions 被访问(也就是subject.getSession())时验证它们是否中止或过时。这意味着,若是没有额外的按期验证,Session orphans(孤儿)将会开始填充会话数据存储。 会话孤儿,若是它们没有按期清除,将会填充会话数据存储(这是很糟糕的)。所以,为了防止丢放孤儿,SessionManager 实现支持SessionValidationScheduler 的概念。SessionValidationScheduler 负责按期地验证会话以确保它们是否须要清理。 Default SessionValidationScheduler 默承认用的SessionValidationScheduler 在全部环境中都是ExecutorServiceSessionValidationScheduler,它使用JDK ScheduledExecutorService 来控制验证频率。 默认地,该实现每小时执行一次验证。你能够经过指定一个新的ExecutorServiceSessionValidationScheduler 实例并指定不一样的间隔(以毫秒为单位)改变速率来更改验证频率: [main] … sessionValidationScheduler = org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler # Default is 3,600,000 millis = 1 hour: sessionValidationScheduler.interval = 3600000 securityManager.sessionManager.sessionValidationScheduler = $sessionValidationScheduler Custom SessionValidationScheduler 若是你但愿提供一个自定义的SessionValidationScheduler 实现,你能够指定它做为默认的SessionManager 实例的一个属性。例如,在shiro.ini 中: [main] … sessionValidationScheduler = com.foo.my.SessionValidationScheduler securityManager.sessionManager.sessionValidationScheduler = $sessionValidationScheduler Disabling Session Validation 在某些状况下,你可能但愿禁用会话验证项,因为你创建了一个超出了Shiro 控制的进程来为你执行验证。例如,也许你正在使用一个企业的Cache 并依赖于缓存的Time To Live 设置来自动地去除旧的会话。或者也许你已经制定了一个计划任务来自动清理一个自定义的数据存储。在这些状况下你能够关掉session validation scheduling: [main] … securityManager.sessionManager.sessionValidationSchedulerEnabled = false 当会话从会话数据存储取回数据时它仍然会被验证,但这会禁用掉Shiro 的按期验证。 Enable Session Validation somewhere 若是你关闭了Shiro 的session validation scheduler,你必须经过其余的机制(计划任务等)来执行按期的会话验证。这是保证会话孤儿不会填充数据存储的惟一方法。 Invalid Session Deletion 正如咱们上面所说的,进行按期的会话验证主要目的是为了删除任何无效的(过时或中止)会话来确保它们不会填充会话数据存储。 默认地,某些应用程序可能不但愿Shiro 自动地删除会话。例如,若是一个应用程序已经提供了一个SessionDAO 备份数据存储查询,也许是应用程序团队但愿旧的或无效的会话在必定的时间内可用。这将容许团队对数据存储运行查询来判断,例如,在上周某个用户建立了多少个会话,或一个用户会话的持续时间,或与之相似报告类型的查询。 在这些情形中,你能够关闭invalid session deletion 项。例如,在shiro.ini 中: [main] … securityManager.sessionManager.deletInvalidSessions = false 请注意!若是你关闭了它,你得为确保你的会话数据存储不耗尽它的空间复杂。你必须本身从你的数据存储中删除无效的会话! 还要注意,即便你阻止了Shiro 删除无效的会话,你仍然应该使用某种会话验证方式——要没经过Shiro 的现有验证机制,要么经过一个你本身提供的自定义的机制(见上述的"Disabling Session Validation"获取更多)。验证机制将会更新你的会话记录以反映无效的状态(例如,何时它是无效的,它最后一次被访问是何时,等等),即便你在其余的一些时间将手动删除它们。 若是你配置Shiro 来让它不会删除无效的会话,你得为确保你的会话数据存储不会耗尽它的空间负责。你必须亲自从你的数据存储删除无效的会话! 另外请注意,禁用会话删除并不等同于禁用session validation schedule(会话验证调度)。你应该老是使用一个会话验证调度机制——不管是Shiro 直接支持或者是你本身的。
相关文章
相关标签/搜索