Shiro 提供了完整的企业级会话管理功能,不依赖于底层容 器(如web容器tomcat),不管 JavaSE 还是 JavaEE 环境都可以使用,提供了会话管理、会话事件监听、会话存储和持久化、容器无关的集群、失效和过期支持、对Web 的透明支持、SSO 单点登录的支持等特性。

一、会话的API
Subject.getSession():即可获取会话;其等价于 Subject.getSession(true),即如果当前没有创建 Session 对象会创建 一个;Subject.getSession(false),如果当前没有创建 Session 则返回 null 。
session.getId():获取当前会话的唯一标识。
session.getHost():获取当前Subject的主机地址。
session.getTimeout():获取当 前Session的过期时间。
session.setTimeout(毫秒):设置当 前Session的过期时间 。
session.getStartTimestamp(): 获取会话的启动时间。
session.getLastAccessTime():获取会话的最后访问时间。如果是 JavaSE 应用需要自己定期调用 session.touch() 去更新最后访问时间;如果是 Web 应用,每次进入 ShiroFilter 都会自动调用 session.touch() 来更新最后访问时间。
session.touch():更新会话最后访问时间。
session.stop():销毁会话。当Subject.logout()时会自动调用 stop 方法来销毁会话。如果在web中,调用 HttpSession. invalidate() 也会自动调用Shiro Session.stop 方法进行销毁Shiro 的会话。
session.setAttribute(key, val):设置会话属性;在整个会话范围内都可以对这些属性进行操作。
session.getAttribute(key): 获取会话属性。
session.removeAttribute(key):删除会话属性。

二、会话监听器
会话监听器用于监听会话创建、过期及停止事件。

public class MySessionListener1 implements SessionListener {  

    @Override  
    public void onStart(Session session) { // 会话创建时触发  
        System.out.println("会话创建:" + session.getId());  
    }  
    
    @Override  
    public void onExpiration(Session session) { // 会话过期时触发  
        System.out.println("会话过期:" + session.getId());  
    }  
    
    @Override  
    public void onStop(Session session) { // 退出或会话过期时触发  
        System.out.println("会话停止:" + session.getId());  
    }    
    
}  

测试:
 我们建议在Controller 层使用原生的 HttpSession。在传统的应用里面不能再 Service 层访问 HttpSession,这时我们就可以使用 Shiro 的Session。
1、使用 HttpSession 给Session 中放入属性 key

@Controller
@RequestMapping("/shiro")
public class ShiroHandler {
	
	@Autowired
	private ShiroService shiroService;
	
	@RequiresRoles({"admin"})
	@RequestMapping("/testShiroAnnotation")
	public String testShiroAnnotation(HttpSession session){
		session.setAttribute("key", "value12345");
		shiroService.testMethod();
		return "redirect:/list.jsp";
	}

}

2、在 Service 层获取 Session 中属性 key 的值

public class ShiroService {
	
	public void testMethod(){
		System.out.println("testMethod, time: " + new Date());
		
		Session session = SecurityUtils.getSubject().getSession();
		Object val = session.getAttribute("key");
		
		System.out.println("Service SessionVal: " + val);
	}
	
}

三、SessionDao
在这里插入图片描述
AbstractSessionDAO 提供了 SessionDAO 的基础实现, 如生成会话ID等。
CachingSessionDAO 提供了对开发者透明的会话缓存的功能,需要设置相应的 CacheManager。
MemorySessionDAO 直接在内存中进行会话维护。
EnterpriseCacheSessionDAO 提供了缓存功能的会话维护,默认情况下使用 MapCache 实现,内部使用 ConcurrentHashMap 保存缓存的会话。
1、在Spring配置文件中配置 SessionManager

<!--  配置 SecurityManager -->     
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="cacheManager" ref="cacheManager"/>
    <property name="authenticator" ref="authenticator"></property>
    
    <property name="realms">
	    <list>
			<ref bean="jdbcRealm"/>
			<ref bean="secondRealm"/>
		</list>
    </property>
    <property name="sessionManager" ref="sessionManager"></property>
</bean>

在这里插入图片描述
2、在 ehcache.xml 配置缓存

<cache name="shiro-activeSessionCache"
   	   eternal="false"
       timeToIdleSeconds="3600"
       timeToLiveSeconds="0"
       overflowToDisk="false"
       statistics="true">
</cache>

3、在数据库中创建表 sessions

create table sessions  (
    id varchar(200),
    sessionvarchar(2000),
    constraint pk_sessions primarykey(id)
) charset=utf8 ENGINE=InnoDB;

4、Session Dao
在这里插入图片描述
在这里插入图片描述
5、SerializableUtils
在这里插入图片描述
四、会话验证
 Shiro 提供了会话验证调度器,用于定期的验证会话是否已过期,如果过期将停止会话。
 出于性能考虑,一般情况下都是获取会话时来验证会话是否过期并停止会话的;但是如在 web 环境中,如果用户不 主动退出是不知道会话是否过期的,因此需要定期的检测会话是否过期,Shiro 提供了会话验证调度器 SessionValidationScheduler。
 Shiro 也提供了使用Quartz会话验证调度器: QuartzSessionValidationScheduler

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐