- 1. shiro中的缓存
- 1.1 引入需要的第三方包
- 1.2 ehcache配置文件
- 1.2 配置spring的配置文件
- 2. shiro中的session
- 2.1 shiro中的session特点和常用方法
- 2.2 如何使用
- 2.3 Session监听
- 2.4 SessionDao
1. shiro中的缓存
在权限验证时每次从数据库中获取权限数据显然是不合适的,更合适方式是将数据缓存到内存,以提高系统性能,shiro中可以方便的配置缓存,具体的配置如下:
1.1 引入需要的第三方包
<!-- shiro依赖包 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro-version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro-version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro-version}</version>
</dependency>
<!-- 缓存需要的包 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring-version}</version>
</dependency>
1.2 ehcache配置文件
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="java.io.tmpdir"/>
<defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"
timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>
<!--name: Cache的名称,必须是唯一的(ehcache会把这个cache放到HashMap里)-->
<!-- <cache name="stuCache" eternal="false" maxElementsInMemory="100"
overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
timeToLiveSeconds="300" memoryStoreEvictionPolicy="LRU"/> -->
</ehcache>
1.2 配置spring的配置文件
<!-- shiro 缓存-->
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"/>
<property name="shared" value="true"></property>
</bean>
<bean id="shrioEhcache" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManager" ref="cacheManagerFactory"></property>
</bean>
<!-- 将自定义的realm注入到安全管理器中 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="shiroRealm" />
<!-- 为安全管理器配置缓存 -->
<property name="cacheManager" ref="shrioEhcache"></property>
</bean>
2. shiro中的session
2.1 shiro中的session特点和常用方法
shiro的session和httpsession概念上是相同的,指定都是客户端和服务器之间的一次会话。
shiro的session的特点如下:
- 不依赖于底层的容器(比如Tomcat),httpsession是依赖于底层容器的,这意味中shiro的session可以脱离容器使用
- 提供了会话管理,会话监听,会话存储等功能, 可以支持会话过期,实现单点登录等。
常用的方法:
Subject.getSession(true/false) 获取session,如果为参数为true,则没有session时会创建session,如果为false则没有session返回空
session.getId() 获取当前会话的ID号
session.getHost() 获取当权会话的主机地址
session.getTimeout() 获取过期时间
session.setTimeout() 设置当前时间
session.getStartTimestamp() 获取会话启动的时间戳
session.getLastAccessTime() 获取会话的最后访问时间
session.touch() 更新最后一次访问时间
session.stop() 销毁会话
session.setAttribute(kay,val)
session.getAttribute(key)
session.removeAttribute(key)
shiro中的session也提供了监听器,和HttpSessionListener类似,提供如下方法:
onStart() -- 监听启动事件
onStop() -- 监听停止事件
onExpiration() -- 监听过期事件
2.2 如何使用
shiro中的session使用起来非常简单,通过设置在HttpSession中的数据,可以在Shiro的Session中直接获取
//在controller中使用HttpSession来设置属性
@PostMapping("/user")
public String getUser(User user, Model model, HttpSession session) {
session.setAttribute("uname", user.getUsername());
...
}
@Service
public class SessionService implements ISessionService {
@Override
public void testSession() {
//在service中通过Subject获取session使用,这里的uname属性是通过HttpSession类设置的
Session session = SecurityUtils.getSubject().getSession();
System.out.println("===== session : " + session.getAttribute("uname"));
}
}
如何验证缓存配置的有效性:
- 首先不配置缓存,在自定义的Realm中输出一些提示信息,启动服务后会发现每次调用登录,或其他配置了权限认证的功能,都会输出提示信息
- 配置缓存,然后重新运行相同的通过,查看后台,加载一次后及不会再有输出
2.3 Session监听
用于监听session的创建,过期等事件,如果在需要时可以再session创建时做些初始化操作,或在过期时做些清理操作。
1) 创建一个自定义监听器
@Slf4j
public class SessionListener extends SessionListenerAdapter {
@Override
public void onStart(Session session) {
log.info("Shiro session onStart .... ");
}
@Override
public void onStop(Session session) {
log.info("Shiro session onStop .... ");
}
@Override
public void onExpiration(Session session) {
log.info("Shiro session onExpiration ....");
}
}
2)配置文件,在spring配置文件中做如下配置
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="shiroRealm" />
<!-- 注入缓存管理器 -->
<property name="cacheManager" ref="shrioEhcache"/>
<!-- session管理器 -->
<property name="sessionManager" ref="sessionManager"/>
</bean>
<!-- session管理器 ,配置自定义监听器,同时需要将该sessionManager配置到securityManager中-->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionListeners">
<list>
<bean class="com.zking.shirodemo.listener.SessionListener"/>
</list>
</property>
</bean>
2.4 SessionDao
实现自定义SessionDao的步骤:
- 编写自定义的SessionDao,集成自EnterpriseCacheSessionDao
- 在spring中配置sessionManager,配置示例
<bean id="sessionManager"
class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- 删除失效session -->
<property name="sessionValidationSchedulerEnabled" value="true" />
<!-- session失效时间(毫秒) -->
<property name="globalSessionTimeout" value="1800000" />
<property name="sessionDAO" ref="customShiroSessionDao" />
</bean>
- 在安全管理器中配置sessionManager
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 自定义realm -->
<property name="realm" ref="customRealm" />
<!-- session管理器 -->
<property name="sessionManager" ref="sessionManager" />
<!-- 缓存管理器 -->
<property name="cacheManager" ref="cacheManager" />
</bean>